Compare commits

..

10 Commits

Author SHA1 Message Date
youyuan.chen
f40874bc90 fix link and generate 2026-07-31 13:45:20 +08:00
youyuan.chen
0d2afbf2bb feat: add Go1 training and MuJoCo deployment 2026-07-26 00:40:06 +08:00
wertyuilife2
28b4516d22 update better default training settings; update new policy and results; update readme. 2026-06-29 03:08:09 +08:00
wertyuilife
f08058fcb8 update readme. 2026-06-22 17:31:50 +08:00
wertyuilife
7f13461612 update history length to 10; update readme; add demo resources; update policy files and deploy config. 2026-06-12 05:20:29 +08:00
wertyuilife
f78f791275 update environment type in Go2RLGymCommand; enable debug vis on play; update gitignore. 2026-06-10 14:25:53 +08:00
wertyuilife
c7a80005c1 fix: reset limited command state 2026-06-10 14:21:36 +08:00
wertyuilife
b3e8033659 update readme. 2026-05-29 19:43:17 +08:00
wty-yy
b0c399c635 Update RoboGauge available checker 2026-05-18 22:23:37 +08:00
wertyuilife
2462c854f7 use official unitree motor as default; disable randomized action delay env; update readme. 2026-05-11 12:26:39 +08:00
42 changed files with 2559 additions and 51 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
deploy/deploy_mujoco/deploy_go2.py whitespace=cr-at-eol

3
.gitignore vendored
View File

@@ -72,16 +72,15 @@ __pycache__/
# ML checkpoints / datasets # ML checkpoints / datasets
*.pth *.pth
*.onnx
*.npz *.npz
*.npy *.npy
# Large ML artifacts (do not commit) # Large ML artifacts (do not commit)
*.pth *.pth
*.ckpt *.ckpt
*.onnx
# logs # logs
logs/ logs/
**/logs/ **/logs/
outputs/ outputs/
.omx/

View File

@@ -1,6 +0,0 @@
Sat Apr 11 17:39:23 2026
WARNING: Nan, Inf or huge value in CTRL at ACTUATOR 9. The simulation is unstable. Time = 4.4000.
Sat Apr 11 17:39:34 2026
WARNING: Nan, Inf or huge value in CTRL at ACTUATOR 9. The simulation is unstable. Time = 4.4000.

108
README.md
View File

@@ -1,20 +1,90 @@
# go2_rl_robotlab <div align="center">
<h1 align="center">Go2 RL RobotLab</h1>
<a href="https://robogauge.github.io/complete/">
<img src="https://img.shields.io/badge/Project-Page-green.svg" alt="Project Page"/>
</a>
<a href="https://robogauge.github.io/static/files/arxiv.pdf">
<img src="https://img.shields.io/badge/Paper-RSS%202026-blue.svg" alt="RSS 2026 Paper"/>
</a>
<a href="https://arxiv.org/abs/2602.00678">
<img src="https://img.shields.io/badge/arXiv-2602.00678-b31b1b.svg" alt="arXiv:2602.00678"/>
</a>
<a href="https://github.com/wty-yy/go2_rl_gym">
<img src="https://img.shields.io/badge/IsaacGym-go2__rl__gym-orange.svg" alt="IsaacGym go2_rl_gym"/>
</a>
</div>
## Overview ## Overview
Train a Unitree Go2 robot in IsaacLab, and deploy policy to MuJoCo for Sim2Sim. For more, see the [project page](https://robogauge.github.io/complete/).
Trains the Unitree Go2 robot using MoE-CTS in IsaacLab and deploys the trained policy to MuJoCo for simulation transfer (Sim2Sim). It is an official [MoE-CTS](https://robogauge.github.io/static/files/arxiv.pdf) algorithm implementation in IsaacLab / RobotLab, as a reproduction of [go2_rl_gym](https://github.com/wty-yy/go2_rl_gym).
It is a reproduction of [go2_rl_gym](https://github.com/wty-yy/go2_rl_gym), adapted to the RobotLab / IsaacLab ecosystem.
--- ---
<p align="center"> <p align="center">
<img src="resources/go2/isaaclab_scene.png" width="70%"/> <img src="resources/results/isaaclab_scene.png" width="70%"/>
</p> </p>
--- ---
## Demos
<p align="center">
<b>Train in IsaacLab → validate with MuJoCo Sim2Sim → evaluate on the real Unitree Go2.</b>
</p>
<table>
<tr>
<td width="50%" align="center">
<b>IsaacLab Play</b><br/>
<sub>Policy rollout in the IsaacLab environment.</sub><br/><br/>
<img src="https://raw.githubusercontent.com/wertyuilife2/picture-bed/main/go2_rl_robotlab/demo-isaaclab.gif" width="80%"/>
</td>
<td width="50%" align="center">
<b>MuJoCo Sim2Sim</b><br/>
<sub>Exported policy running in MuJoCo before real-world deployment.</sub><br/><br/>
<img src="https://raw.githubusercontent.com/wertyuilife2/picture-bed/main/go2_rl_robotlab/demo-sim2sim.gif" width="80%"/>
</td>
</tr>
<tr>
<td width="50%" align="center">
<b>Real Robot</b><br/>
<sub>Robust walking front on stairs.</sub><br/><br/>
<img src="https://raw.githubusercontent.com/wertyuilife2/picture-bed/main/go2_rl_robotlab/demo-real-walk-front.gif" width="100%"/>
</td>
<td width="50%" align="center">
<b>Real Robot</b><br/>
<sub>Robust walking sideways on stairs.</sub><br/><br/>
<img src="https://raw.githubusercontent.com/wertyuilife2/picture-bed/main/go2_rl_robotlab/demo-real-walk-side.gif" width="100%"/>
</td>
</tr>
</table>
---
## RoboGauge Benchmark
<p align="center">
<b><a href="https://github.com/wty-yy/RoboGauge">RoboGauge</a> score comparison between go2_rl_robotlab and the original go2_rl_gym.</b>
</p>
<p align="center">
<img src="resources/results/robogauge_compare.png" width="100%"/>
</p>
### Algorithm Results (Best Checkpoint Results)
| Model | Score | Tracking | Safety | Quality | Level |
| --- | --- | --- | --- | --- | --- |
| go2_moe_cts (go2_rl_robotlab) | **0.6984** | **0.7055** | **0.8159** | **0.7693** | **8.30** |
| go2_moe_cts (go2_rl_gym) | 0.6713 | 0.6669 | 0.7857 | 0.7392 | 7.85 |
| [CTS](https://arxiv.org/pdf/2405.10830) vanilla | 0.5786 | 0.5755 | 0.7066 | 0.6624 | 6.83 |
| [HIM](https://github.com/InternRobotics/HIMLoco) | 0.5379 | 0.5453 | 0.6476 | 0.6050 | 6.19 |
| [DreamWaQ](https://arxiv.org/abs/2301.10602) | 0.5054 | 0.5105 | 0.6149 | 0.5730 | 5.74 |
---
## Installation Guide ## Installation Guide
### 1. Install IsaacLab ### 1. Install IsaacLab
@@ -64,6 +134,10 @@ python scripts/rsl_rl/train.py --task=RobotLab-Go2-v0 --headless
python scripts/rsl_rl/play.py --task=RobotLab-Go2-v0 python scripts/rsl_rl/play.py --task=RobotLab-Go2-v0
``` ```
The Go1 adaptation is available on the `go1` branch as
`RobotLab-Go1-v0`; see [docs/go1.md](docs/go1.md) for its training, export,
observation, and MuJoCo deployment details.
--- ---
### Training with RoboGauge Evaluation ### Training with RoboGauge Evaluation
@@ -180,18 +254,18 @@ xml_path: "{ROOT_DIR}/resources/go2/your-custom-scene.xml"
## Differences from `go2_rl_gym` ## Differences from `go2_rl_gym`
- Different tracking reward formulation (fixed sigma vs. dynamic sigma) - Motor:
- Different rewards: - use official unitree motor model instead of simple PD controller.
- lower joint_acc_l2 weight in Lab due to physics-step level implementation and sensitivity to outliers - Rewards:
- extra joint_pos_penalty_l1 reward in Lab due to better performance - 2x tracking reward weights due to better performance.
- Lack domain_rand: randomize_motor_strength - different tracking reward form (fixed sigma vs. dynamic sigma).
- lower joint_acc_l2 weight in Lab due to physics-step level implementation and sensitivity to outliers.
--- - extra joint_pos_penalty_l1 reward in Lab due to better performance.
- Domain randomization:
## TODO - no randomized action delay, use motor-level delay instead.
- no motor strength randomization due to implementation constraints in Lab.
- Try replacing ActionManager-level delay with `DelayedPDActuatorCfg` or `UnitreeActuatorCfg_Go2HV`, and make sure the randomization of motor parameters works correctly. - History length: 10 in Lab vs. 5 in Gym, due to better performance with longer history in Lab.
- Terrain Difficulty: use lab's continuous difficulty levels.
--- ---
## Acknowledgements ## Acknowledgements

View File

@@ -0,0 +1,43 @@
policy_path: "{ROOT_DIR}/deploy/pre_train/go1/policy.pt"
xml_path: "{ROOT_DIR}/resources/go1/stairs_and_slope.xml"
render_fps: 300
video_fps: 60
save_video: false
simulation_duration: 60000000.0
simulation_dt: 0.002
control_decimation: 10
base_init_pos: [0.0, 0.0, 0.34]
base_init_quat: [1.0, 0.0, 0.0, 0.0]
# Deployment defaults to no extra delay. Training randomizes 0-4 physics steps;
# this script's delay buffer is measured in 20 ms policy steps instead.
actuator_delay_min: 0
actuator_delay_max: 0
actuator_delay_seed: 0
kps: [28.0, 28.0, 28.0, 28.0, 28.0, 28.0, 28.0, 28.0, 28.0, 28.0, 28.0, 28.0]
kds: [0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7]
default_angles: [-0.1, 0.8, -1.5, 0.1, 0.8, -1.5,
-0.1, 1.0, -1.5, 0.1, 1.0, -1.5]
lin_vel_scale: 2.0
ang_vel_scale: 0.25
dof_pos_scale: 1.0
dof_vel_scale: 0.05
action_pos_scale: 0.25
cmd_scale: [1.0, 1.0, 1.0]
num_actions: 12
num_obs: 45
max_cmd: [1.0, 1.0, 1.0]
cmd_init: [0.5, 0.0, 0.0]
history_len: 10
mujoco_joint_names: &joint_names
[FR_hip_joint, FR_thigh_joint, FR_calf_joint,
FL_hip_joint, FL_thigh_joint, FL_calf_joint,
RR_hip_joint, RR_thigh_joint, RR_calf_joint,
RL_hip_joint, RL_thigh_joint, RL_calf_joint]
model_joint_names: *joint_names

View File

@@ -1,8 +1,8 @@
policy_path: "{ROOT_DIR}/deploy/pre_train/go2/xxx.pt" # policy.pt exported by running scripts/rsl_rl/play.py policy_path: "{ROOT_DIR}/deploy/pre_train/go2/go2_moe_cts_176k_0.6984.pt" # policy.pt exported by running scripts/rsl_rl/play.py
xml_path: "{ROOT_DIR}/resource/go2/stairs.xml" xml_path: "{ROOT_DIR}/resources/go2/stairs_and_slope.xml"
render_fps: 240 render_fps: 300
video_fps: 60 video_fps: 60
save_video: false save_video: false

View File

@@ -0,0 +1,12 @@
"""Run an exported Go1 CTS policy in MuJoCo.
The model, observations, actions, and MuJoCo actuators all use the Unitree SDK
joint order: FR, FL, RR, RL. The exported policy maintains its own history and
therefore consumes one 45-dimensional observation frame per call.
"""
from deploy_go2 import main
if __name__ == "__main__":
main("go1.yaml")

View File

@@ -12,6 +12,8 @@ Notes:
This script currently uses CONFIG_NAME = "go2.yaml" and does not expose CLI flags. This script currently uses CONFIG_NAME = "go2.yaml" and does not expose CLI flags.
""" """
from __future__ import annotations
import time import time
from pathlib import Path from pathlib import Path
@@ -95,9 +97,9 @@ def build_single_obs(features: dict[str, np.ndarray], layout: list[tuple[str, in
return np.concatenate([features[name] for name, _ in layout], axis=0).astype(np.float32, copy=False) return np.concatenate([features[name] for name, _ in layout], axis=0).astype(np.float32, copy=False)
def main() -> None: def main(config_name: str = CONFIG_NAME) -> None:
"""Run MuJoCo simulation and deploy the CTS policy in closed-loop control.""" """Run MuJoCo simulation and deploy the CTS policy in closed-loop control."""
cfg = load_config(CONFIG_NAME) cfg = load_config(config_name)
layout = [ layout = [
("ang_vel", 3), ("ang_vel", 3),
("gravity", 3), ("gravity", 3),

View File

@@ -1,5 +1,7 @@
"""Shared helpers for MuJoCo deployment scripts.""" """Shared helpers for MuJoCo deployment scripts."""
from __future__ import annotations
from collections import deque from collections import deque
from pathlib import Path from pathlib import Path
from types import SimpleNamespace from types import SimpleNamespace

View File

@@ -0,0 +1 @@

Binary file not shown.

Binary file not shown.

63
docs/go1.md Normal file
View File

@@ -0,0 +1,63 @@
# Go1 Adaptation
The `go1` branch adds the `RobotLab-Go1-v0` IsaacLab task and a matching
MuJoCo deployment. It uses the complete Unitree Go1 URDF/MuJoCo model.
## Interface
- Policy joint order: `FR, FL, RR, RL`, with hip, thigh, calf for each leg.
- Single-frame observation: 45 values in this order:
body angular velocity (3), projected gravity (3), velocity command (3),
relative joint position (12), joint velocity (12), previous action (12).
- Actor history: 10 frames, or 450 values.
- Action: 12 normalized joint-position offsets, scaled by `0.25 rad` and added
to the default joint angles.
- Policy frequency: 50 Hz (`0.005 s` physics step and decimation 4).
- PD gains: `Kp=28`, `Kd=0.7`; torque is limited to `33.5 Nm`.
- Training randomizes actuator delay over 0-4 physics steps (0-20 ms). The
MuJoCo config defaults to zero extra delay because its delay setting is in
20 ms policy steps.
## Train
Install the editable packages as described in the main README, then run:
```bash
cd go2_rl_robotlab
python scripts/rsl_rl/train.py \
--task=RobotLab-Go1-v0 \
--num_envs=4096 \
--max_iterations=5000 \
--headless
```
## Play And Export
`play.py` exports both `policy.pt` and `policy.onnx` into the checkpoint run's
`exported/` directory before starting the rollout.
```bash
python scripts/rsl_rl/play.py \
--task=RobotLab-Go1-v0 \
--num_envs=64 \
--checkpoint=/absolute/path/to/model_5000.pt
```
## MuJoCo
Place the exported TorchScript file at
`deploy/pre_train/go1/policy.pt`, or edit `policy_path` in
`deploy/deploy_mujoco/configs/go1.yaml`. Then run:
```bash
MUJOCO_GL=glfw python deploy/deploy_mujoco/deploy_go1.py
```
Set `xml_path` in `go1.yaml` to select `flat.xml`, `stairs.xml`, `boxes.xml`,
or `stairs_and_slope.xml`.
## Actuator Assumption
The Go1 asset publishes a `33.5 Nm` effort limit but does not include measured
torque-speed knee points. The training actuator therefore uses the known effort
limit with delayed PD control instead of reusing the Go2-HV torque-speed curve.

696
resources/go1/boxes.xml Normal file
View File

@@ -0,0 +1,696 @@
<mujoco model="boxes">
<include file="go1.xml" />
<statistic center="0 0 0.1" extent="0.8" />
<visual>
<headlight diffuse="0.6 0.6 0.6" ambient="0.3 0.3 0.3" specular="0 0 0" />
<rgba haze="0.15 0.25 0.35 1" />
<global azimuth="-130" elevation="-20" />
</visual>
<asset>
<texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="3072" />
<texture type="2d" name="groundplane" builtin="checker" mark="edge" rgb1="0.2 0.3 0.4" rgb2="0.1 0.2 0.3" markrgb="0.8 0.8 0.8" width="300" height="300" />
<material name="groundplane" texture="groundplane" texuniform="true" texrepeat="5 5" reflectance="0.2" />
</asset>
<worldbody>
<light pos="0 0 1.5" dir="0 0 -1" directional="true" />
<geom name="floor" size="0 0 0.05" type="plane" material="groundplane" />
<!-- Rough terrain: full coverage with dense bumps -->
<geom pos="0.5 -2.0 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="0.8 -2.0 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="1.1 -2.0 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="1.4 -2.0 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="1.7 -2.0 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="2.0 -2.0 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="2.3 -2.0 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="2.6 -2.0 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="2.9 -2.0 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="3.2 -2.0 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="3.5 -2.0 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="3.8 -2.0 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="4.1 -2.0 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="4.4 -2.0 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="4.7 -2.0 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="5.0 -2.0 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="5.3 -2.0 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="5.6 -2.0 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="5.9 -2.0 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="6.2 -2.0 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="6.5 -2.0 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="6.8 -2.0 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="7.1 -2.0 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="7.4 -2.0 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="7.7 -2.0 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="8.0 -2.0 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="8.3 -2.0 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="8.6 -2.0 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="8.9 -2.0 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="9.2 -2.0 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="9.5 -2.0 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="9.8 -2.0 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="10.1 -2.0 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="10.4 -2.0 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="10.7 -2.0 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="11.0 -2.0 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="11.3 -2.0 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="11.6 -2.0 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="11.9 -2.0 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="12.2 -2.0 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="12.5 -2.0 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="12.8 -2.0 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="13.1 -2.0 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="13.4 -2.0 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="13.7 -2.0 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="14.0 -2.0 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="14.3 -2.0 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="14.6 -2.0 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="0.5 -1.7 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="0.8 -1.7 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="1.1 -1.7 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="1.4 -1.7 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="1.7 -1.7 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="2.0 -1.7 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="2.3 -1.7 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="2.6 -1.7 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="2.9 -1.7 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="3.2 -1.7 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="3.5 -1.7 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="3.8 -1.7 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="4.1 -1.7 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="4.4 -1.7 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="4.7 -1.7 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="5.0 -1.7 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="5.3 -1.7 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="5.6 -1.7 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="5.9 -1.7 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="6.2 -1.7 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="6.5 -1.7 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="6.8 -1.7 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="7.1 -1.7 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="7.4 -1.7 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="7.7 -1.7 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="8.0 -1.7 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="8.3 -1.7 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="8.6 -1.7 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="8.9 -1.7 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="9.2 -1.7 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="9.5 -1.7 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="9.8 -1.7 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="10.1 -1.7 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="10.4 -1.7 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="10.7 -1.7 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="11.0 -1.7 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="11.3 -1.7 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="11.6 -1.7 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="11.9 -1.7 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="12.2 -1.7 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="12.5 -1.7 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="12.8 -1.7 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="13.1 -1.7 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="13.4 -1.7 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="13.7 -1.7 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="14.0 -1.7 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="14.3 -1.7 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="14.6 -1.7 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="0.5 -1.4 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="0.8 -1.4 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="1.1 -1.4 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="1.4 -1.4 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="1.7 -1.4 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="2.0 -1.4 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="2.3 -1.4 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="2.6 -1.4 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="2.9 -1.4 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="3.2 -1.4 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="3.5 -1.4 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="3.8 -1.4 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="4.1 -1.4 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="4.4 -1.4 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="4.7 -1.4 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="5.0 -1.4 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="5.3 -1.4 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="5.6 -1.4 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="5.9 -1.4 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="6.2 -1.4 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="6.5 -1.4 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="6.8 -1.4 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="7.1 -1.4 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="7.4 -1.4 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="7.7 -1.4 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="8.0 -1.4 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="8.3 -1.4 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="8.6 -1.4 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="8.9 -1.4 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="9.2 -1.4 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="9.5 -1.4 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="9.8 -1.4 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="10.1 -1.4 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="10.4 -1.4 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="10.7 -1.4 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="11.0 -1.4 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="11.3 -1.4 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="11.6 -1.4 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="11.9 -1.4 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="12.2 -1.4 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="12.5 -1.4 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="12.8 -1.4 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="13.1 -1.4 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="13.4 -1.4 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="13.7 -1.4 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="14.0 -1.4 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="14.3 -1.4 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="14.6 -1.4 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="0.5 -1.1 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="0.8 -1.1 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="1.1 -1.1 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="1.4 -1.1 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="1.7 -1.1 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="2.0 -1.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="2.3 -1.1 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="2.6 -1.1 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="2.9 -1.1 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="3.2 -1.1 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="3.5 -1.1 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="3.8 -1.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="4.1 -1.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="4.4 -1.1 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="4.7 -1.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="5.0 -1.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="5.3 -1.1 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="5.6 -1.1 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="5.9 -1.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="6.2 -1.1 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="6.5 -1.1 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="6.8 -1.1 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="7.1 -1.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="7.4 -1.1 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="7.7 -1.1 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="8.0 -1.1 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="8.3 -1.1 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="8.6 -1.1 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="8.9 -1.1 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="9.2 -1.1 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="9.5 -1.1 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="9.8 -1.1 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="10.1 -1.1 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="10.4 -1.1 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="10.7 -1.1 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="11.0 -1.1 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="11.3 -1.1 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="11.6 -1.1 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="11.9 -1.1 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="12.2 -1.1 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="12.5 -1.1 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="12.8 -1.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="13.1 -1.1 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="13.4 -1.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="13.7 -1.1 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="14.0 -1.1 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="14.3 -1.1 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="14.6 -1.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="0.5 -0.8 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="0.8 -0.8 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="1.1 -0.8 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="1.4 -0.8 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="1.7 -0.8 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="2.0 -0.8 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="2.3 -0.8 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="2.6 -0.8 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="2.9 -0.8 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="3.2 -0.8 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="3.5 -0.8 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="3.8 -0.8 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="4.1 -0.8 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="4.4 -0.8 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="4.7 -0.8 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="5.0 -0.8 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="5.3 -0.8 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="5.6 -0.8 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="5.9 -0.8 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="6.2 -0.8 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="6.5 -0.8 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="6.8 -0.8 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="7.1 -0.8 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="7.4 -0.8 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="7.7 -0.8 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="8.0 -0.8 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="8.3 -0.8 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="8.6 -0.8 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="8.9 -0.8 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="9.2 -0.8 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="9.5 -0.8 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="9.8 -0.8 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="10.1 -0.8 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="10.4 -0.8 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="10.7 -0.8 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="11.0 -0.8 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="11.3 -0.8 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="11.6 -0.8 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="11.9 -0.8 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="12.2 -0.8 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="12.5 -0.8 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="12.8 -0.8 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="13.1 -0.8 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="13.4 -0.8 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="13.7 -0.8 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="14.0 -0.8 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="14.3 -0.8 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="14.6 -0.8 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="0.5 -0.5 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="0.8 -0.5 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="1.1 -0.5 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="1.4 -0.5 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="1.7 -0.5 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="2.0 -0.5 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="2.3 -0.5 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="2.6 -0.5 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="2.9 -0.5 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="3.2 -0.5 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="3.5 -0.5 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="3.8 -0.5 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="4.1 -0.5 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="4.4 -0.5 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="4.7 -0.5 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="5.0 -0.5 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="5.3 -0.5 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="5.6 -0.5 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="5.9 -0.5 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="6.2 -0.5 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="6.5 -0.5 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="6.8 -0.5 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="7.1 -0.5 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="7.4 -0.5 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="7.7 -0.5 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="8.0 -0.5 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="8.3 -0.5 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="8.6 -0.5 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="8.9 -0.5 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="9.2 -0.5 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="9.5 -0.5 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="9.8 -0.5 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="10.1 -0.5 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="10.4 -0.5 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="10.7 -0.5 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="11.0 -0.5 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="11.3 -0.5 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="11.6 -0.5 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="11.9 -0.5 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="12.2 -0.5 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="12.5 -0.5 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="12.8 -0.5 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="13.1 -0.5 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="13.4 -0.5 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="13.7 -0.5 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="14.0 -0.5 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="14.3 -0.5 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="14.6 -0.5 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="0.5 -0.2 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="0.8 -0.2 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="1.1 -0.2 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="1.4 -0.2 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="1.7 -0.2 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="2.0 -0.2 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="2.3 -0.2 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="2.6 -0.2 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="2.9 -0.2 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="3.2 -0.2 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="3.5 -0.2 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="3.8 -0.2 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="4.1 -0.2 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="4.4 -0.2 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="4.7 -0.2 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="5.0 -0.2 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="5.3 -0.2 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="5.6 -0.2 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="5.9 -0.2 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="6.2 -0.2 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="6.5 -0.2 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="6.8 -0.2 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="7.1 -0.2 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="7.4 -0.2 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="7.7 -0.2 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="8.0 -0.2 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="8.3 -0.2 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="8.6 -0.2 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="8.9 -0.2 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="9.2 -0.2 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="9.5 -0.2 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="9.8 -0.2 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="10.1 -0.2 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="10.4 -0.2 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="10.7 -0.2 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="11.0 -0.2 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="11.3 -0.2 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="11.6 -0.2 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="11.9 -0.2 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="12.2 -0.2 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="12.5 -0.2 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="12.8 -0.2 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="13.1 -0.2 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="13.4 -0.2 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="13.7 -0.2 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="14.0 -0.2 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="14.3 -0.2 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="14.6 -0.2 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="0.5 0.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="0.8 0.1 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="1.1 0.1 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="1.4 0.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="1.7 0.1 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="2.0 0.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="2.3 0.1 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="2.6 0.1 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="2.9 0.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="3.2 0.1 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="3.5 0.1 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="3.8 0.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="4.1 0.1 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="4.4 0.1 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="4.7 0.1 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="5.0 0.1 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="5.3 0.1 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="5.6 0.1 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="5.9 0.1 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="6.2 0.1 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="6.5 0.1 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="6.8 0.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="7.1 0.1 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="7.4 0.1 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="7.7 0.1 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="8.0 0.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="8.3 0.1 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="8.6 0.1 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="8.9 0.1 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="9.2 0.1 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="9.5 0.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="9.8 0.1 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="10.1 0.1 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="10.4 0.1 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="10.7 0.1 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="11.0 0.1 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="11.3 0.1 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="11.6 0.1 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="11.9 0.1 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="12.2 0.1 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="12.5 0.1 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="12.8 0.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="13.1 0.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="13.4 0.1 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="13.7 0.1 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="14.0 0.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="14.3 0.1 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="14.6 0.1 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="0.5 0.4 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="0.8 0.4 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="1.1 0.4 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="1.4 0.4 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="1.7 0.4 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="2.0 0.4 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="2.3 0.4 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="2.6 0.4 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="2.9 0.4 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="3.2 0.4 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="3.5 0.4 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="3.8 0.4 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="4.1 0.4 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="4.4 0.4 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="4.7 0.4 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="5.0 0.4 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="5.3 0.4 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="5.6 0.4 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="5.9 0.4 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="6.2 0.4 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="6.5 0.4 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="6.8 0.4 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="7.1 0.4 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="7.4 0.4 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="7.7 0.4 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="8.0 0.4 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="8.3 0.4 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="8.6 0.4 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="8.9 0.4 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="9.2 0.4 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="9.5 0.4 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="9.8 0.4 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="10.1 0.4 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="10.4 0.4 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="10.7 0.4 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="11.0 0.4 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="11.3 0.4 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="11.6 0.4 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="11.9 0.4 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="12.2 0.4 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="12.5 0.4 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="12.8 0.4 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="13.1 0.4 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="13.4 0.4 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="13.7 0.4 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="14.0 0.4 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="14.3 0.4 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="14.6 0.4 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="0.5 0.7 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="0.8 0.7 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="1.1 0.7 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="1.4 0.7 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="1.7 0.7 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="2.0 0.7 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="2.3 0.7 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="2.6 0.7 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="2.9 0.7 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="3.2 0.7 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="3.5 0.7 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="3.8 0.7 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="4.1 0.7 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="4.4 0.7 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="4.7 0.7 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="5.0 0.7 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="5.3 0.7 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="5.6 0.7 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="5.9 0.7 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="6.2 0.7 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="6.5 0.7 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="6.8 0.7 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="7.1 0.7 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="7.4 0.7 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="7.7 0.7 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="8.0 0.7 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="8.3 0.7 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="8.6 0.7 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="8.9 0.7 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="9.2 0.7 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="9.5 0.7 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="9.8 0.7 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="10.1 0.7 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="10.4 0.7 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="10.7 0.7 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="11.0 0.7 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="11.3 0.7 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="11.6 0.7 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="11.9 0.7 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="12.2 0.7 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="12.5 0.7 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="12.8 0.7 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="13.1 0.7 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="13.4 0.7 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="13.7 0.7 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="14.0 0.7 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="14.3 0.7 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="14.6 0.7 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="0.5 1.0 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="0.8 1.0 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="1.1 1.0 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="1.4 1.0 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="1.7 1.0 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="2.0 1.0 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="2.3 1.0 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="2.6 1.0 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="2.9 1.0 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="3.2 1.0 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="3.5 1.0 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="3.8 1.0 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="4.1 1.0 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="4.4 1.0 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="4.7 1.0 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="5.0 1.0 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="5.3 1.0 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="5.6 1.0 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="5.9 1.0 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="6.2 1.0 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="6.5 1.0 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="6.8 1.0 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="7.1 1.0 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="7.4 1.0 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="7.7 1.0 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="8.0 1.0 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="8.3 1.0 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="8.6 1.0 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="8.9 1.0 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="9.2 1.0 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="9.5 1.0 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="9.8 1.0 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="10.1 1.0 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="10.4 1.0 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="10.7 1.0 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="11.0 1.0 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="11.3 1.0 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="11.6 1.0 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="11.9 1.0 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="12.2 1.0 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="12.5 1.0 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="12.8 1.0 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="13.1 1.0 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="13.4 1.0 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="13.7 1.0 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="14.0 1.0 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="14.3 1.0 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="14.6 1.0 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="0.5 1.3 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="0.8 1.3 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="1.1 1.3 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="1.4 1.3 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="1.7 1.3 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="2.0 1.3 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="2.3 1.3 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="2.6 1.3 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="2.9 1.3 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="3.2 1.3 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="3.5 1.3 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="3.8 1.3 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="4.1 1.3 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="4.4 1.3 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="4.7 1.3 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="5.0 1.3 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="5.3 1.3 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="5.6 1.3 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="5.9 1.3 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="6.2 1.3 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="6.5 1.3 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="6.8 1.3 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="7.1 1.3 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="7.4 1.3 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="7.7 1.3 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="8.0 1.3 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="8.3 1.3 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="8.6 1.3 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="8.9 1.3 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="9.2 1.3 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="9.5 1.3 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="9.8 1.3 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="10.1 1.3 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="10.4 1.3 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="10.7 1.3 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="11.0 1.3 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="11.3 1.3 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="11.6 1.3 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="11.9 1.3 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="12.2 1.3 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="12.5 1.3 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="12.8 1.3 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="13.1 1.3 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="13.4 1.3 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="13.7 1.3 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="14.0 1.3 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="14.3 1.3 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="14.6 1.3 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="0.5 1.6 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="0.8 1.6 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="1.1 1.6 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="1.4 1.6 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="1.7 1.6 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="2.0 1.6 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="2.3 1.6 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="2.6 1.6 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="2.9 1.6 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="3.2 1.6 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="3.5 1.6 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="3.8 1.6 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="4.1 1.6 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="4.4 1.6 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="4.7 1.6 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="5.0 1.6 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="5.3 1.6 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="5.6 1.6 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="5.9 1.6 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="6.2 1.6 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="6.5 1.6 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="6.8 1.6 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="7.1 1.6 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="7.4 1.6 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="7.7 1.6 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="8.0 1.6 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="8.3 1.6 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="8.6 1.6 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="8.9 1.6 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="9.2 1.6 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="9.5 1.6 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="9.8 1.6 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="10.1 1.6 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="10.4 1.6 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="10.7 1.6 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="11.0 1.6 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="11.3 1.6 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="11.6 1.6 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="11.9 1.6 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="12.2 1.6 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="12.5 1.6 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="12.8 1.6 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="13.1 1.6 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="13.4 1.6 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="13.7 1.6 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="14.0 1.6 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="14.3 1.6 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="14.6 1.6 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="0.5 1.9 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="0.8 1.9 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="1.1 1.9 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="1.4 1.9 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="1.7 1.9 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="2.0 1.9 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="2.3 1.9 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="2.6 1.9 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="2.9 1.9 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="3.2 1.9 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="3.5 1.9 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="3.8 1.9 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="4.1 1.9 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="4.4 1.9 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="4.7 1.9 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="5.0 1.9 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="5.3 1.9 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="5.6 1.9 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="5.9 1.9 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="6.2 1.9 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="6.5 1.9 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="6.8 1.9 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="7.1 1.9 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="7.4 1.9 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="7.7 1.9 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="8.0 1.9 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="8.3 1.9 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="8.6 1.9 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="8.9 1.9 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="9.2 1.9 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="9.5 1.9 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="9.8 1.9 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="10.1 1.9 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="10.4 1.9 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="10.7 1.9 0.03" type="box" size="0.15 0.15 0.03" />
<geom pos="11.0 1.9 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="11.3 1.9 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="11.6 1.9 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="11.9 1.9 0.1" type="box" size="0.15 0.15 0.1" />
<geom pos="12.2 1.9 0.04" type="box" size="0.15 0.15 0.04" />
<geom pos="12.5 1.9 0.08" type="box" size="0.15 0.15 0.08" />
<geom pos="12.8 1.9 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="13.1 1.9 0.09" type="box" size="0.15 0.15 0.09" />
<geom pos="13.4 1.9 0.05" type="box" size="0.15 0.15 0.05" />
<geom pos="13.7 1.9 0.07" type="box" size="0.15 0.15 0.07" />
<geom pos="14.0 1.9 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="14.3 1.9 0.06" type="box" size="0.15 0.15 0.06" />
<geom pos="14.6 1.9 0.09" type="box" size="0.15 0.15 0.09" />
</worldbody>
</mujoco>

22
resources/go1/flat.xml Normal file
View File

@@ -0,0 +1,22 @@
<mujoco model="flat">
<include file="go1.xml"/>
<statistic center="1.0 0.7 1.0" extent="0.8"/>
<visual>
<headlight diffuse="0.6 0.6 0.6" ambient="0.1 0.1 0.1" specular="0.9 0.9 0.9"/>
<rgba haze="0.15 0.25 0.35 1"/>
<global azimuth="-140" elevation="-20"/>
</visual>
<asset>
<texture type="skybox" builtin="flat" rgb1="0 0 0" rgb2="0 0 0" width="512" height="3072"/>
<texture type="2d" name="groundplane" builtin="checker" mark="edge" rgb1="0.2 0.3 0.4" rgb2="0.1 0.2 0.3" markrgb="0.8 0.8 0.8" width="300" height="300"/>
<material name="groundplane" texture="groundplane" texuniform="true" texrepeat="5 5" reflectance="0.2"/>
</asset>
<worldbody>
<light pos="1 0 3.5" dir="0 0 -1" directional="true"/>
<geom name="floor" size="0 0 0.05" type="plane" material="groundplane"/>
</worldbody>
</mujoco>

198
resources/go1/go1.xml Normal file
View File

@@ -0,0 +1,198 @@
<mujoco model="go1">
<compiler angle="radian" meshdir="meshes" />
<size njmax="500" nconmax="100" />
<option gravity='0 0 -9.806' iterations='50' solver='Newton' timestep='0.002'/>
<default>
<geom contype="1" conaffinity="1" friction="0.6 0.3 0.3" rgba="0.5 0.6 0.7 1" margin="0.001" group="0"/>
<light castshadow="false" diffuse="1 1 1"/>
<motor ctrlrange="-33.5 33.5" ctrllimited="true"/>
<camera fovy="60"/>
<joint damping="0.01" armature="0.01" frictionloss="0.2" />
</default>
<asset>
<mesh name="trunk" file="trunk.stl" />
<mesh name="hip" file="hip.stl" />
<mesh name="thigh_mirror" file="thigh_mirror.stl" />
<mesh name="calf" file="calf.stl" />
<mesh name="thigh" file="thigh.stl" />
</asset>
<worldbody>
<body name="base_link" pos="0 0 0.35">
<inertial pos="0.0116053 0.00442221 0.000106692" quat="0.0111438 0.707126 -0.00935374 0.706938" mass="4.801" diaginertia="0.0447997 0.0366257 0.0162187" />
<freejoint name="root" />
<geom type="mesh" contype="0" conaffinity="0" group="1" rgba="0.913725 0.913725 0.847059 1" mesh="trunk" />
<geom size="0.13 0.04675 0.057" type="box" rgba="0.913725 0.913725 0.847059 1" />
<geom size="0.0005 0.0005 0.0005" pos="-0.01592 -0.06659 -0.00617" type="box" contype="0" conaffinity="0" group="1" rgba="0.8 0 0 0" />
<geom size="0.0005 0.0005 0.0005" pos="-0.01592 -0.06659 -0.00617" type="box" rgba="0.8 0 0 0" />
<site name="imu" pos="0 0 0"/>
<body name="FR_hip" pos="0.1881 -0.04675 0">
<inertial pos="-0.00406411 -0.0193463 4.50733e-06" quat="0.467526 0.531662 -0.466259 0.530431" mass="0.679292" diaginertia="0.00131334 0.00122648 0.000728484" />
<joint name="FR_hip_joint" pos="0 0 0" axis="1 0 0" limited="true" range="-0.802851 0.802851" />
<geom quat="0 1 0 0" type="mesh" contype="0" conaffinity="0" group="1" rgba="0.913725 0.913725 0.847059 1" mesh="hip" />
<geom size="0.046 0.02" pos="0 -0.045 0" quat="0.707107 0.707107 0 0" type="cylinder" rgba="0.913725 0.913725 0.847059 0" />
<geom size="0.031 0.02" pos="0 -0.07 0" quat="0.707107 0.707107 0 0" type="cylinder" rgba="0.913725 0.913725 0.847059 0" />
<body name="FR_thigh" pos="0 -0.08 0">
<inertial pos="-0.003468 0.018947 -0.032736" quat="0.999266 0.00067676 -0.0382978 0.000639813" mass="0.898919" diaginertia="0.00542178 0.00514246 0.000998869" />
<joint name="FR_thigh_joint" pos="0 0 0" axis="0 1 0" limited="true" range="-1.0472 4.18879" />
<geom type="mesh" contype="0" conaffinity="0" group="1" rgba="0.913725 0.913725 0.847059 1" mesh="thigh_mirror" />
<geom size="0.1065 0.01225 0.017" pos="0 0 -0.1065" quat="0.707107 0 0.707107 0" type="box" rgba="0.913725 0.913725 0.847059 0" />
<body name="FR_calf" pos="0 0 -0.213">
<inertial pos="0.00455603 0.0009473 -0.147239" quat="0.762045 0.00970173 0.0180098 0.647201" mass="0.218015" diaginertia="0.00399678 0.00398122 3.99428e-05" />
<joint name="FR_calf_joint" pos="0 0 0" axis="0 1 0" limited="true" range="-2.69653 -0.916298" />
<geom type="mesh" contype="0" conaffinity="0" group="1" rgba="0 0 0 1" mesh="calf" />
<geom size="0.1065 0.008 0.008" pos="0 0 -0.1065" quat="0.707107 0 0.707107 0" type="box" rgba="0 0 0 0" />
<geom size="0.01" pos="0 0 -0.213" contype="0" conaffinity="0" group="1" rgba="0 0 0 1" />
<geom name="FR" size="0.02" pos="0 0 -0.213" rgba="0 0 0 1" />
<body name="FR_foot" pos="0 0 -0.213" />
</body>
</body>
</body>
<body name="FL_hip" pos="0.1881 0.04675 0">
<inertial pos="-0.00406411 0.0193463 4.50733e-06" quat="0.531662 0.467526 -0.530431 0.466259" mass="0.679292" diaginertia="0.00131334 0.00122648 0.000728484" />
<joint name="FL_hip_joint" pos="0 0 0" axis="1 0 0" limited="true" range="-0.802851 0.802851" />
<geom type="mesh" contype="0" conaffinity="0" group="1" rgba="0.913725 0.913725 0.847059 1" mesh="hip" />
<geom size="0.046 0.02" pos="0 0.045 0" quat="0.707107 0.707107 0 0" type="cylinder" rgba="0.913725 0.913725 0.847059 0" />
<geom size="0.031 0.02" pos="0 0.07 0" quat="0.707107 0.707107 0 0" type="cylinder" rgba="0.913725 0.913725 0.847059 0" />
<body name="FL_thigh" pos="0 0.08 0">
<inertial pos="-0.003468 -0.018947 -0.032736" quat="0.999266 -0.00067676 -0.0382978 -0.000639813" mass="0.898919" diaginertia="0.00542178 0.00514246 0.000998869" />
<joint name="FL_thigh_joint" pos="0 0 0" axis="0 1 0" limited="true" range="-1.0472 4.18879" />
<geom type="mesh" contype="0" conaffinity="0" group="1" rgba="0.913725 0.913725 0.847059 1" mesh="thigh" />
<geom size="0.1065 0.01225 0.017" pos="0 0 -0.1065" quat="0.707107 0 0.707107 0" type="box" rgba="0.913725 0.913725 0.847059 0" />
<body name="FL_calf" pos="0 0 -0.213">
<inertial pos="0.00455603 0.0009473 -0.147239" quat="0.762045 0.00970173 0.0180098 0.647201" mass="0.218015" diaginertia="0.00399678 0.00398122 3.99428e-05" />
<joint name="FL_calf_joint" pos="0 0 0" axis="0 1 0" limited="true" range="-2.69653 -0.916298" />
<geom type="mesh" contype="0" conaffinity="0" group="1" rgba="0 0 0 1" mesh="calf" />
<geom size="0.1065 0.008 0.008" pos="0 0 -0.1065" quat="0.707107 0 0.707107 0" type="box" rgba="0.913725 0.913725 0.847059 0" />
<geom size="0.01" pos="0 0 -0.213" contype="0" conaffinity="0" group="1" rgba="0 0 0 1" />
<geom name="FL" size="0.02" pos="0 0 -0.213" rgba="0 0 0 1" />
<body name="FL_foot" pos="0 0 -0.213" />
</body>
</body>
</body>
<body name="RR_hip" pos="-0.1881 -0.04675 0">
<inertial pos="0.00406411 -0.0193463 4.50733e-06" quat="0.530431 0.466259 -0.531662 0.467526" mass="0.679292" diaginertia="0.00131334 0.00122648 0.000728484" />
<joint name="RR_hip_joint" pos="0 0 0" axis="1 0 0" limited="true" range="-0.802851 0.802851" />
<geom quat="0 0 0 -1" type="mesh" contype="0" conaffinity="0" group="1" rgba="0.913725 0.913725 0.847059 1" mesh="hip" />
<geom size="0.046 0.02" quat="0.707107 0.707107 0 0" type="cylinder" rgba="0.913725 0.913725 0.847059 1" />
<geom size="0.046 0.02" pos="0 -0.045 0" quat="0.707107 0.707107 0 0" type="cylinder" rgba="0.913725 0.913725 0.847059 0" />
<geom size="0.031 0.02" pos="0 -0.07 0" quat="0.707107 0.707107 0 0" type="cylinder" rgba="0.913725 0.913725 0.847059 0" />
<body name="RR_thigh" pos="0 -0.08 0">
<inertial pos="-0.003468 0.018947 -0.032736" quat="0.999266 0.00067676 -0.0382978 0.000639813" mass="0.898919" diaginertia="0.00542178 0.00514246 0.000998869" />
<joint name="RR_thigh_joint" pos="0 0 0" axis="0 1 0" limited="true" range="-1.0472 4.18879" />
<geom type="mesh" contype="0" conaffinity="0" group="1" rgba="0.913725 0.913725 0.847059 1" mesh="thigh_mirror" />
<geom size="0.1065 0.01225 0.017" pos="0 0 -0.1065" quat="0.707107 0 0.707107 0" type="box" rgba="0.913725 0.913725 0.847059 0" />
<body name="RR_calf" pos="0 0 -0.213">
<inertial pos="0.00455603 0.0009473 -0.147239" quat="0.762045 0.00970173 0.0180098 0.647201" mass="0.218015" diaginertia="0.00399678 0.00398122 3.99428e-05" />
<joint name="RR_calf_joint" pos="0 0 0" axis="0 1 0" limited="true" range="-2.69653 -0.916298" />
<geom type="mesh" contype="0" conaffinity="0" group="1" rgba="0 0 0 1" mesh="calf" />
<geom size="0.1065 0.008 0.008" pos="0 0 -0.1065" quat="0.707107 0 0.707107 0" type="box" rgba="0 0 0 0" />
<geom size="0.01" pos="0 0 -0.213" contype="0" conaffinity="0" group="1" rgba="0 0 0 1" />
<geom name="RR" size="0.02" pos="0 0 -0.213" rgba="0 0 0 1" />
<body name="RR_foot" pos="0 0 -0.213" />
</body>
</body>
</body>
<body name="RL_hip" pos="-0.1881 0.04675 0">
<inertial pos="0.00406411 0.0193463 4.50733e-06" quat="0.466259 0.530431 -0.467526 0.531662" mass="0.679292" diaginertia="0.00131334 0.00122648 0.000728484" />
<joint name="RL_hip_joint" pos="0 0 0" axis="1 0 0" limited="true" range="-0.802851 0.802851" />
<geom quat="0 0 1 0" type="mesh" contype="0" conaffinity="0" group="1" rgba="0.913725 0.913725 0.847059 1" mesh="hip" />
<geom size="0.046 0.02" quat="0.707107 0.707107 0 0" type="cylinder" rgba="0.913725 0.913725 0.847059 1" />
<geom size="0.046 0.02" pos="0 0.045 0" quat="0.707107 0.707107 0 0" type="cylinder" rgba="0.913725 0.913725 0.847059 0" />
<geom size="0.031 0.02" pos="0 0.07 0" quat="0.707107 0.707107 0 0" type="cylinder" rgba="0.913725 0.913725 0.847059 0" />
<body name="RL_thigh" pos="0 0.08 0">
<inertial pos="-0.003468 -0.018947 -0.032736" quat="0.999266 -0.00067676 -0.0382978 -0.000639813" mass="0.898919" diaginertia="0.00542178 0.00514246 0.000998869" />
<joint name="RL_thigh_joint" pos="0 0 0" axis="0 1 0" limited="true" range="-1.0472 4.18879" />
<geom type="mesh" contype="0" conaffinity="0" group="1" rgba="0.913725 0.913725 0.847059 1" mesh="thigh" />
<geom size="0.1065 0.01225 0.017" pos="0 0 -0.1065" quat="0.707107 0 0.707107 0" type="box" rgba="0.913725 0.913725 0.847059 0" />
<body name="RL_calf" pos="0 0 -0.213">
<inertial pos="0.00455603 0.0009473 -0.147239" quat="0.762045 0.00970173 0.0180098 0.647201" mass="0.218015" diaginertia="0.00399678 0.00398122 3.99428e-05" />
<joint name="RL_calf_joint" pos="0 0 0" axis="0 1 0" limited="true" range="-2.69653 -0.916298" />
<geom type="mesh" contype="0" conaffinity="0" group="1" rgba="0 0 0 1" mesh="calf" />
<geom size="0.1065 0.008 0.008" pos="0 0 -0.1065" quat="0.707107 0 0.707107 0" type="box" rgba="0 0 0 0" />
<geom size="0.01" pos="0 0 -0.213" contype="0" conaffinity="0" group="1" rgba="0 0 0 1" />
<geom name="RL" size="0.02" pos="0 0 -0.213" rgba="0 0 0 1" />
<body name="RL_foot" pos="0 0 -0.213" />
</body>
</body>
</body>
</body>
</worldbody>
<actuator>
<motor name="FR_hip" gear="1" joint="FR_hip_joint"/>
<motor name="FR_thigh" gear="1" joint="FR_thigh_joint"/>
<motor name="FR_calf" gear="1" joint="FR_calf_joint"/>
<motor name="FL_hip" gear="1" joint="FL_hip_joint"/>
<motor name="FL_thigh" gear="1" joint="FL_thigh_joint"/>
<motor name="FL_calf" gear="1" joint="FL_calf_joint"/>
<motor name="RR_hip" gear="1" joint="RR_hip_joint"/>
<motor name="RR_thigh" gear="1" joint="RR_thigh_joint"/>
<motor name="RR_calf" gear="1" joint="RR_calf_joint" />
<motor name="RL_hip" gear="1" joint="RL_hip_joint"/>
<motor name="RL_thigh" gear="1" joint="RL_thigh_joint"/>
<motor name="RL_calf" gear="1" joint="RL_calf_joint"/>
</actuator>
<sensor>
<jointpos name="FR_hip_pos" joint="FR_hip_joint"/>
<jointpos name="FR_thigh_pos" joint="FR_thigh_joint"/>
<jointpos name="FR_calf_pos" joint="FR_calf_joint"/>
<jointpos name="FL_hip_pos" joint="FL_hip_joint"/>
<jointpos name="FL_thigh_pos" joint="FL_thigh_joint"/>
<jointpos name="FL_calf_pos" joint="FL_calf_joint"/>
<jointpos name="RR_hip_pos" joint="RR_hip_joint"/>
<jointpos name="RR_thigh_pos" joint="RR_thigh_joint"/>
<jointpos name="RR_calf_pos" joint="RR_calf_joint" />
<jointpos name="RL_hip_pos" joint="RL_hip_joint"/>
<jointpos name="RL_thigh_pos" joint="RL_thigh_joint"/>
<jointpos name="RL_calf_pos" joint="RL_calf_joint"/>
<jointvel name="FR_hip_vel" joint="FR_hip_joint"/>
<jointvel name="FR_thigh_vel" joint="FR_thigh_joint"/>
<jointvel name="FR_calf_vel" joint="FR_calf_joint"/>
<jointvel name="FL_hip_vel" joint="FL_hip_joint"/>
<jointvel name="FL_thigh_vel" joint="FL_thigh_joint"/>
<jointvel name="FL_calf_vel" joint="FL_calf_joint"/>
<jointvel name="RR_hip_vel" joint="RR_hip_joint"/>
<jointvel name="RR_thigh_vel" joint="RR_thigh_joint"/>
<jointvel name="RR_calf_vel" joint="RR_calf_joint" />
<jointvel name="RL_hip_vel" joint="RL_hip_joint"/>
<jointvel name="RL_thigh_vel" joint="RL_thigh_joint"/>
<jointvel name="RL_calf_vel" joint="RL_calf_joint"/>
<jointactuatorfrc name="FR_hip_torque" joint="FR_hip_joint" />
<jointactuatorfrc name="FR_thigh_torque" joint="FR_thigh_joint" />
<jointactuatorfrc name="FR_calf_torque" joint="FR_calf_joint" />
<jointactuatorfrc name="FL_hip_torque" joint="FL_hip_joint" />
<jointactuatorfrc name="FL_thigh_torque" joint="FL_thigh_joint" />
<jointactuatorfrc name="FL_calf_torque" joint="FL_calf_joint" />
<jointactuatorfrc name="RR_hip_torque" joint="RR_hip_joint" />
<jointactuatorfrc name="RR_thigh_torque" joint="RR_thigh_joint" />
<jointactuatorfrc name="RR_calf_torque" joint="RR_calf_joint" />
<jointactuatorfrc name="RL_hip_torque" joint="RL_hip_joint" />
<jointactuatorfrc name="RL_thigh_torque" joint="RL_thigh_joint" />
<jointactuatorfrc name="RL_calf_torque" joint="RL_calf_joint" />
<accelerometer name="Body_Acc" site="imu"/>
<gyro name="Body_Gyro" site="imu"/>
<framepos name="Body_Pos" objtype="site" objname="imu"/>
<framelinvel name="Body_LinVel" objtype="site" objname="imu"/>
<framequat name="Body_Quat" objtype="site" objname="imu"/>
</sensor>
</mujoco>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

28
resources/go1/stairs.xml Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,39 @@
<mujoco model="stairs_and_slope">
<include file="go1.xml"/>
<statistic center="0 0 0.1" extent="0.8"/>
<visual>
<headlight diffuse="0.6 0.6 0.6" ambient="0.3 0.3 0.3" specular="0 0 0"/>
<rgba haze="0.15 0.25 0.35 1"/>
<global azimuth="-130" elevation="-20"/>
</visual>
<asset>
<texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="3072"/>
<texture type="2d" name="groundplane" builtin="checker" mark="edge" rgb1="0.2 0.3 0.4" rgb2="0.1 0.2 0.3"
markrgb="0.8 0.8 0.8" width="300" height="300"/>
<material name="groundplane" texture="groundplane" texuniform="true" texrepeat="5 5" reflectance="0.2"/>
</asset>
<worldbody>
<light pos="0 0 1.5" dir="0 0 -1" directional="true"/>
<geom name="floor" size="0 0 0.05" type="plane" material="groundplane"/>
<body name="stairs" pos="2 0 0">
<geom name="step_0" type="box" size="0.15 3.0 0.095" pos="0.15 0 0.095" rgba="1 1 1 1"/>
<geom name="step_1" type="box" size="0.15 3.0 0.095" pos="0.45 0 0.285" rgba="1 1 1 1"/>
<geom name="step_2" type="box" size="0.15 3.0 0.095" pos="0.75 0 0.475" rgba="1 1 1 1"/>
<geom name="step_3" type="box" size="0.15 3.0 0.095" pos="1.05 0 0.665" rgba="1 1 1 1"/>
<geom name="step_4" type="box" size="0.15 3.0 0.095" pos="1.35 0 0.855" rgba="1 1 1 1"/>
<geom name="step_5" type="box" size="0.15 3.0 0.095" pos="1.65 0 1.045" rgba="1 1 1 1"/>
<geom name="step_6" type="box" size="0.15 3.0 0.095" pos="1.95 0 1.235" rgba="1 1 1 1"/>
<geom name="step_7" type="box" size="0.15 3.0 0.095" pos="2.25 0 1.425" rgba="1 1 1 1"/>
<geom name="step_8" type="box" size="0.15 3.0 0.095" pos="2.55 0 1.615" rgba="1 1 1 1"/>
<geom name="step_9" type="box" size="0.15 3.0 0.095" pos="2.85 0 1.805" rgba="1 1 1 1"/>
</body>
<!-- 斜坡从最后一阶末端X=6开始向下倾斜0.4rad水平长度约4.493m,白色 -->
<geom name="ramp" type="box" size="2.2465 3.0 0.1" pos="7.0465 0 0.95" rgba="1 1 1 1" euler="0 0.4 0"/>
</worldbody>
</mujoco>

581
resources/go1/urdf/go1.urdf Normal file
View File

@@ -0,0 +1,581 @@
<?xml version="1.0" ?>
<robot name="go1_description" xmlns:xacro="http://www.ros.org/wiki/xacro">
<material name="black">
<color rgba="0.0 0.0 0.0 1.0"/>
</material>
<material name="blue">
<color rgba="0.0 0.0 0.8 1.0"/>
</material>
<material name="green">
<color rgba="0.0 0.8 0.0 1.0"/>
</material>
<material name="grey">
<color rgba="0.2 0.2 0.2 1.0"/>
</material>
<material name="silver">
<color rgba="0.913725490196 0.913725490196 0.847058823529 1.0"/>
</material>
<material name="orange">
<color rgba="1.0 0.423529411765 0.0392156862745 1.0"/>
</material>
<material name="brown">
<color rgba="0.870588235294 0.811764705882 0.764705882353 1.0"/>
</material>
<material name="red">
<color rgba="0.8 0.0 0.0 1.0"/>
</material>
<material name="white">
<color rgba="1.0 1.0 1.0 1.0"/>
</material>
<link name="base">
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<box size="0.001 0.001 0.001"/>
</geometry>
</visual>
</link>
<joint name="floating_base" type="fixed">
<origin rpy="0 0 0" xyz="0 0 0"/>
<parent link="base"/>
<child link="trunk"/>
</joint>
<link name="trunk">
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="../meshes/trunk.stl" scale="1 1 1"/>
</geometry>
<material name="silver"/>
</visual>
<collision>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<box size="0.3762 0.0935 0.114"/>
</geometry>
</collision>
<inertial>
<origin rpy="0 0 0" xyz="0.011611 0.004437 0.000108"/>
<mass value="4.8"/>
<inertia ixx="0.016130741919" ixy="0.000593180607" ixz="7.324662e-06" iyy="0.036507810812" iyz="2.0969537e-05" izz="0.044693872053"/>
</inertial>
</link>
<joint name="imu_joint" type="fixed">
<parent link="trunk"/>
<child link="imu_link"/>
<origin rpy="0 0 0" xyz="-0.01592 -0.06659 -0.00617"/>
</joint>
<link name="imu_link">
<inertial>
<mass value="0.001"/>
<origin rpy="0 0 0" xyz="0 0 0"/>
<inertia ixx="0.0001" ixy="0" ixz="0" iyy="0.0001" iyz="0" izz="0.0001"/>
</inertial>
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<box size="0.001 0.001 0.001"/>
</geometry>
<material name="red"/>
</visual>
<!-- <collision>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<box size=".001 .001 .001"/>
</geometry>
</collision> -->
</link>
<joint name="FR_hip_joint" type="revolute">
<origin rpy="0 0 0" xyz="0.1881 -0.04675 0"/>
<parent link="trunk"/>
<child link="FR_hip"/>
<axis xyz="1 0 0"/>
<dynamics damping="0" friction="0"/>
<limit effort="33.5" lower="-0.802851455917" upper="0.802851455917" velocity="50"/>
</joint>
<link name="FR_hip">
<visual>
<origin rpy="3.14159265359 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="../meshes/hip.stl" scale="1 1 1"/>
</geometry>
<material name="silver"/>
</visual>
<collision>
<origin rpy="1.57079632679 0 0" xyz="0 -0.045 0"/>
<geometry>
<cylinder length="0.04" radius="0.046"/>
</geometry>
</collision>
<inertial>
<origin rpy="0 0 0" xyz="-0.00541 0.00074 6e-06"/>
<mass value="0.510299"/>
<inertia ixx="0.00030528937" ixy="7.788013e-06" ixz="2.2016e-07" iyy="0.000590894859" iyz="1.7175e-08" izz="0.000396594572"/>
</inertial>
</link>
<joint name="FR_hip_fixed" type="fixed">
<origin rpy="0 0 0" xyz="0 -0.08 0"/>
<parent link="FR_hip"/>
<child link="FR_thigh_shoulder"/>
</joint>
<!-- this link is only for collision -->
<link name="FR_thigh_shoulder">
<!-- <collision>
<origin rpy="1.57079632679 0 0" xyz="0 0 0"/>
<geometry>
<cylinder length="0.032" radius="0.041"/>
</geometry>
</collision> -->
</link>
<joint name="FR_thigh_joint" type="revolute">
<origin rpy="0 0 0" xyz="0 -0.08 0"/>
<parent link="FR_hip"/>
<child link="FR_thigh"/>
<axis xyz="0 1 0"/>
<dynamics damping="0" friction="0"/>
<limit effort="33.5" lower="-1.0471975512" upper="4.18879020479" velocity="28"/>
</joint>
<link name="FR_thigh">
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="../meshes/thigh_mirror.stl" scale="1 1 1"/>
</geometry>
<material name="silver"/>
</visual>
<collision>
<origin rpy="0 1.57079632679 0" xyz="0 0 -0.1065"/>
<geometry>
<box size="0.213 0.0245 0.034"/>
</geometry>
</collision>
<inertial>
<origin rpy="0 0 0" xyz="-0.003468 0.018947 -0.032736"/>
<mass value="0.898919"/>
<inertia ixx="0.005395867678" ixy="-1.02809e-07" ixz="0.000337529085" iyy="0.005142451046" iyz="5.816563e-06" izz="0.00102478732"/>
</inertial>
</link>
<joint name="FR_calf_joint" type="revolute">
<origin rpy="0 0 0" xyz="0 0 -0.213"/>
<parent link="FR_thigh"/>
<child link="FR_calf"/>
<axis xyz="0 1 0"/>
<dynamics damping="0" friction="0"/>
<limit effort="33.5" lower="-2.69653369433" upper="-0.916297857297" velocity="28"/>
</joint>
<link name="FR_calf">
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="../meshes/calf.stl" scale="1 1 1"/>
</geometry>
<material name="black"/>
</visual>
<collision>
<origin rpy="0 1.57079632679 0" xyz="0 0 -0.1065"/>
<geometry>
<box size="0.213 0.016 0.016"/>
</geometry>
</collision>
<inertial>
<origin rpy="0 0 0" xyz="0.006286 0.001307 -0.122269"/>
<mass value="0.158015"/>
<inertia ixx="0.003607648222" ixy="1.494971e-06" ixz="-0.000132778525" iyy="0.003626771492" iyz="-2.8638535e-05" izz="3.5148003e-05"/>
</inertial>
</link>
<joint name="FR_foot_fixed" type="fixed" dont_collapse="true">
<origin rpy="0 0 0" xyz="0 0 -0.213"/>
<parent link="FR_calf"/>
<child link="FR_foot"/>
</joint>
<link name="FR_foot">
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<sphere radius="0.01"/>
</geometry>
<material name="black"/>
</visual>
<collision>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<sphere radius="0.02"/>
</geometry>
</collision>
<inertial>
<mass value="0.06"/>
<inertia ixx="9.6e-06" ixy="0.0" ixz="0.0" iyy="9.6e-06" iyz="0.0" izz="9.6e-06"/>
</inertial>
</link>
<joint name="FL_hip_joint" type="revolute">
<origin rpy="0 0 0" xyz="0.1881 0.04675 0"/>
<parent link="trunk"/>
<child link="FL_hip"/>
<axis xyz="1 0 0"/>
<dynamics damping="0" friction="0"/>
<limit effort="33.5" lower="-0.802851455917" upper="0.802851455917" velocity="50"/>
</joint>
<link name="FL_hip">
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="../meshes/hip.stl" scale="1 1 1"/>
</geometry>
<material name="silver"/>
</visual>
<collision>
<origin rpy="1.57079632679 0 0" xyz="0 0.045 0"/>
<geometry>
<cylinder length="0.04" radius="0.046"/>
</geometry>
</collision>
<inertial>
<origin rpy="0 0 0" xyz="-0.00541 -0.00074 6e-06"/>
<mass value="0.510299"/>
<inertia ixx="0.00030528937" ixy="-7.788013e-06" ixz="2.2016e-07" iyy="0.000590894859" iyz="-1.7175e-08" izz="0.000396594572"/>
</inertial>
</link>
<joint name="FL_hip_fixed" type="fixed">
<origin rpy="0 0 0" xyz="0 0.08 0"/>
<parent link="FL_hip"/>
<child link="FL_thigh_shoulder"/>
</joint>
<!-- this link is only for collision -->
<link name="FL_thigh_shoulder">
<!-- <collision>
<origin rpy="1.57079632679 0 0" xyz="0 0 0"/>
<geometry>
<cylinder length="0.032" radius="0.041"/>
</geometry>
</collision> -->
</link>
<joint name="FL_thigh_joint" type="revolute">
<origin rpy="0 0 0" xyz="0 0.08 0"/>
<parent link="FL_hip"/>
<child link="FL_thigh"/>
<axis xyz="0 1 0"/>
<dynamics damping="0" friction="0"/>
<limit effort="33.5" lower="-1.0471975512" upper="4.18879020479" velocity="28"/>
</joint>
<link name="FL_thigh">
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="../meshes/thigh.stl" scale="1 1 1"/>
</geometry>
<material name="silver"/>
</visual>
<collision>
<origin rpy="0 1.57079632679 0" xyz="0 0 -0.1065"/>
<geometry>
<box size="0.213 0.0245 0.034"/>
</geometry>
</collision>
<inertial>
<origin rpy="0 0 0" xyz="-0.003468 -0.018947 -0.032736"/>
<mass value="0.898919"/>
<inertia ixx="0.005395867678" ixy="1.02809e-07" ixz="0.000337529085" iyy="0.005142451046" iyz="-5.816563e-06" izz="0.00102478732"/>
</inertial>
</link>
<joint name="FL_calf_joint" type="revolute">
<origin rpy="0 0 0" xyz="0 0 -0.213"/>
<parent link="FL_thigh"/>
<child link="FL_calf"/>
<axis xyz="0 1 0"/>
<dynamics damping="0" friction="0"/>
<limit effort="33.5" lower="-2.69653369433" upper="-0.916297857297" velocity="28"/>
</joint>
<link name="FL_calf">
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="../meshes/calf.stl" scale="1 1 1"/>
</geometry>
<material name="silver"/>
</visual>
<collision>
<origin rpy="0 1.57079632679 0" xyz="0 0 -0.1065"/>
<geometry>
<box size="0.213 0.016 0.016"/>
</geometry>
</collision>
<inertial>
<origin rpy="0 0 0" xyz="0.006286 0.001307 -0.122269"/>
<mass value="0.158015"/>
<inertia ixx="0.003607648222" ixy="1.494971e-06" ixz="-0.000132778525" iyy="0.003626771492" iyz="-2.8638535e-05" izz="3.5148003e-05"/>
</inertial>
</link>
<joint name="FL_foot_fixed" type="fixed" dont_collapse="true">
<origin rpy="0 0 0" xyz="0 0 -0.213"/>
<parent link="FL_calf"/>
<child link="FL_foot"/>
</joint>
<link name="FL_foot">
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<sphere radius="0.01"/>
</geometry>
<material name="black"/>
</visual>
<collision>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<sphere radius="0.02"/>
</geometry>
</collision>
<inertial>
<mass value="0.06"/>
<inertia ixx="9.6e-06" ixy="0.0" ixz="0.0" iyy="9.6e-06" iyz="0.0" izz="9.6e-06"/>
</inertial>
</link>
<joint name="RR_hip_joint" type="revolute">
<origin rpy="0 0 0" xyz="-0.1881 -0.04675 0"/>
<parent link="trunk"/>
<child link="RR_hip"/>
<axis xyz="1 0 0"/>
<dynamics damping="0" friction="0"/>
<limit effort="33.5" lower="-0.802851455917" upper="0.802851455917" velocity="50"/>
</joint>
<link name="RR_hip">
<visual>
<origin rpy="3.14159265359 3.14159265359 0" xyz="0 0 0"/>
<geometry>
<mesh filename="../meshes/hip.stl" scale="1 1 1"/>
</geometry>
<material name="silver"/>
</visual>
<collision>
<origin rpy="1.57079632679 0 0" xyz="0 -0.045 0"/>
<geometry>
<cylinder length="0.04" radius="0.046"/>
</geometry>
</collision>
<inertial>
<origin rpy="0 0 0" xyz="0.00541 0.00074 6e-06"/>
<mass value="0.510299"/>
<inertia ixx="0.00030528937" ixy="-7.788013e-06" ixz="-2.2016e-07" iyy="0.000590894859" iyz="1.7175e-08" izz="0.000396594572"/>
</inertial>
</link>
<joint name="RR_hip_fixed" type="fixed">
<origin rpy="0 0 0" xyz="0 -0.08 0"/>
<parent link="RR_hip"/>
<child link="RR_thigh_shoulder"/>
</joint>
<!-- this link is only for collision -->
<link name="RR_thigh_shoulder">
<!-- <collision>
<origin rpy="1.57079632679 0 0" xyz="0 0 0"/>
<geometry>
<cylinder length="0.032" radius="0.041"/>
</geometry>
</collision> -->
</link>
<joint name="RR_thigh_joint" type="revolute">
<origin rpy="0 0 0" xyz="0 -0.08 0"/>
<parent link="RR_hip"/>
<child link="RR_thigh"/>
<axis xyz="0 1 0"/>
<dynamics damping="0" friction="0"/>
<limit effort="33.5" lower="-1.0471975512" upper="4.18879020479" velocity="28"/>
</joint>
<link name="RR_thigh">
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="../meshes/thigh_mirror.stl" scale="1 1 1"/>
</geometry>
<material name="silver"/>
</visual>
<collision>
<origin rpy="0 1.57079632679 0" xyz="0 0 -0.1065"/>
<geometry>
<box size="0.213 0.0245 0.034"/>
</geometry>
</collision>
<inertial>
<origin rpy="0 0 0" xyz="-0.003468 0.018947 -0.032736"/>
<mass value="0.898919"/>
<inertia ixx="0.005395867678" ixy="-1.02809e-07" ixz="0.000337529085" iyy="0.005142451046" iyz="5.816563e-06" izz="0.00102478732"/>
</inertial>
</link>
<joint name="RR_calf_joint" type="revolute">
<origin rpy="0 0 0" xyz="0 0 -0.213"/>
<parent link="RR_thigh"/>
<child link="RR_calf"/>
<axis xyz="0 1 0"/>
<dynamics damping="0" friction="0"/>
<limit effort="33.5" lower="-2.69653369433" upper="-0.916297857297" velocity="28"/>
</joint>
<link name="RR_calf">
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="../meshes/calf.stl" scale="1 1 1"/>
</geometry>
<material name="black"/>
</visual>
<collision>
<origin rpy="0 1.57079632679 0" xyz="0 0 -0.1065"/>
<geometry>
<box size="0.213 0.016 0.016"/>
</geometry>
</collision>
<inertial>
<origin rpy="0 0 0" xyz="0.006286 0.001307 -0.122269"/>
<mass value="0.158015"/>
<inertia ixx="0.003607648222" ixy="1.494971e-06" ixz="-0.000132778525" iyy="0.003626771492" iyz="-2.8638535e-05" izz="3.5148003e-05"/>
</inertial>
</link>
<joint name="RR_foot_fixed" type="fixed" dont_collapse="true">
<origin rpy="0 0 0" xyz="0 0 -0.213"/>
<parent link="RR_calf"/>
<child link="RR_foot"/>
</joint>
<link name="RR_foot">
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<sphere radius="0.01"/>
</geometry>
<material name="black"/>
</visual>
<collision>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<sphere radius="0.02"/>
</geometry>
</collision>
<inertial>
<mass value="0.06"/>
<inertia ixx="9.6e-06" ixy="0.0" ixz="0.0" iyy="9.6e-06" iyz="0.0" izz="9.6e-06"/>
</inertial>
</link>
<joint name="RL_hip_joint" type="revolute">
<origin rpy="0 0 0" xyz="-0.1881 0.04675 0"/>
<parent link="trunk"/>
<child link="RL_hip"/>
<axis xyz="1 0 0"/>
<dynamics damping="0" friction="0"/>
<limit effort="33.5" lower="-0.802851455917" upper="0.802851455917" velocity="50"/>
</joint>
<link name="RL_hip">
<visual>
<origin rpy="0 3.14159265359 0" xyz="0 0 0"/>
<geometry>
<mesh filename="../meshes/hip.stl" scale="1 1 1"/>
</geometry>
<material name="silver"/>
</visual>
<collision>
<origin rpy="1.57079632679 0 0" xyz="0 0.045 0"/>
<geometry>
<cylinder length="0.04" radius="0.046"/>
</geometry>
</collision>
<inertial>
<origin rpy="0 0 0" xyz="0.00541 -0.00074 6e-06"/>
<mass value="0.510299"/>
<inertia ixx="0.00030528937" ixy="7.788013e-06" ixz="-2.2016e-07" iyy="0.000590894859" iyz="-1.7175e-08" izz="0.000396594572"/>
</inertial>
</link>
<joint name="RL_hip_fixed" type="fixed">
<origin rpy="0 0 0" xyz="0 0.08 0"/>
<parent link="RL_hip"/>
<child link="RL_thigh_shoulder"/>
</joint>
<!-- this link is only for collision -->
<link name="RL_thigh_shoulder">
<!-- <collision>
<origin rpy="1.57079632679 0 0" xyz="0 0 0"/>
<geometry>
<cylinder length="0.032" radius="0.041"/>
</geometry>
</collision> -->
</link>
<joint name="RL_thigh_joint" type="revolute">
<origin rpy="0 0 0" xyz="0 0.08 0"/>
<parent link="RL_hip"/>
<child link="RL_thigh"/>
<axis xyz="0 1 0"/>
<dynamics damping="0" friction="0"/>
<limit effort="33.5" lower="-1.0471975512" upper="4.18879020479" velocity="28"/>
</joint>
<link name="RL_thigh">
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="../meshes/thigh.stl" scale="1 1 1"/>
</geometry>
<material name="silver"/>
</visual>
<collision>
<origin rpy="0 1.57079632679 0" xyz="0 0 -0.1065"/>
<geometry>
<box size="0.213 0.0245 0.034"/>
</geometry>
</collision>
<inertial>
<origin rpy="0 0 0" xyz="-0.003468 -0.018947 -0.032736"/>
<mass value="0.898919"/>
<inertia ixx="0.005395867678" ixy="1.02809e-07" ixz="0.000337529085" iyy="0.005142451046" iyz="-5.816563e-06" izz="0.00102478732"/>
</inertial>
</link>
<joint name="RL_calf_joint" type="revolute">
<origin rpy="0 0 0" xyz="0 0 -0.213"/>
<parent link="RL_thigh"/>
<child link="RL_calf"/>
<axis xyz="0 1 0"/>
<dynamics damping="0" friction="0"/>
<limit effort="33.5" lower="-2.69653369433" upper="-0.916297857297" velocity="28"/>
</joint>
<link name="RL_calf">
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="../meshes/calf.stl" scale="1 1 1"/>
</geometry>
<material name="black"/>
</visual>
<collision>
<origin rpy="0 1.57079632679 0" xyz="0 0 -0.1065"/>
<geometry>
<box size="0.213 0.016 0.016"/>
</geometry>
</collision>
<inertial>
<origin rpy="0 0 0" xyz="0.006286 0.001307 -0.122269"/>
<mass value="0.158015"/>
<inertia ixx="0.003607648222" ixy="1.494971e-06" ixz="-0.000132778525" iyy="0.003626771492" iyz="-2.8638535e-05" izz="3.5148003e-05"/>
</inertial>
</link>
<joint name="RL_foot_fixed" type="fixed" dont_collapse="true">
<origin rpy="0 0 0" xyz="0 0 -0.213"/>
<parent link="RL_calf"/>
<child link="RL_foot"/>
</joint>
<link name="RL_foot">
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<sphere radius="0.01"/>
</geometry>
<material name="black"/>
</visual>
<collision>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<sphere radius="0.02"/>
</geometry>
</collision>
<inertial>
<mass value="0.06"/>
<inertia ixx="9.6e-06" ixy="0.0" ixz="0.0" iyy="9.6e-06" iyz="0.0" izz="9.6e-06"/>
</inertial>
</link>
</robot>

View File

@@ -0,0 +1,39 @@
<mujoco model="stairs_and_slope">
<include file="go2.xml"/>
<statistic center="0 0 0.1" extent="0.8"/>
<visual>
<headlight diffuse="0.6 0.6 0.6" ambient="0.3 0.3 0.3" specular="0 0 0"/>
<rgba haze="0.15 0.25 0.35 1"/>
<global azimuth="-130" elevation="-20"/>
</visual>
<asset>
<texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="3072"/>
<texture type="2d" name="groundplane" builtin="checker" mark="edge" rgb1="0.2 0.3 0.4" rgb2="0.1 0.2 0.3"
markrgb="0.8 0.8 0.8" width="300" height="300"/>
<material name="groundplane" texture="groundplane" texuniform="true" texrepeat="5 5" reflectance="0.2"/>
</asset>
<worldbody>
<light pos="0 0 1.5" dir="0 0 -1" directional="true"/>
<geom name="floor" size="0 0 0.05" type="plane" material="groundplane"/>
<body name="stairs" pos="2 0 0">
<geom name="step_0" type="box" size="0.15 3.0 0.095" pos="0.15 0 0.095" rgba="1 1 1 1"/>
<geom name="step_1" type="box" size="0.15 3.0 0.095" pos="0.45 0 0.285" rgba="1 1 1 1"/>
<geom name="step_2" type="box" size="0.15 3.0 0.095" pos="0.75 0 0.475" rgba="1 1 1 1"/>
<geom name="step_3" type="box" size="0.15 3.0 0.095" pos="1.05 0 0.665" rgba="1 1 1 1"/>
<geom name="step_4" type="box" size="0.15 3.0 0.095" pos="1.35 0 0.855" rgba="1 1 1 1"/>
<geom name="step_5" type="box" size="0.15 3.0 0.095" pos="1.65 0 1.045" rgba="1 1 1 1"/>
<geom name="step_6" type="box" size="0.15 3.0 0.095" pos="1.95 0 1.235" rgba="1 1 1 1"/>
<geom name="step_7" type="box" size="0.15 3.0 0.095" pos="2.25 0 1.425" rgba="1 1 1 1"/>
<geom name="step_8" type="box" size="0.15 3.0 0.095" pos="2.55 0 1.615" rgba="1 1 1 1"/>
<geom name="step_9" type="box" size="0.15 3.0 0.095" pos="2.85 0 1.805" rgba="1 1 1 1"/>
</body>
<!-- 斜坡从最后一阶末端X=6开始向下倾斜0.4rad水平长度约4.493m,白色 -->
<geom name="ramp" type="box" size="2.2465 3.0 0.1" pos="7.0465 0 0.95" rgba="1 1 1 1" euler="0 0.4 0"/>
</worldbody>
</mujoco>

View File

Before

Width:  |  Height:  |  Size: 2.5 MiB

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 KiB

View File

@@ -112,6 +112,7 @@ def fix_commands(env_cfg: ManagerBasedRLEnvCfg | DirectRLEnvCfg | DirectMARLEnvC
ang_vel_z=(fixed_ang_z, fixed_ang_z), ang_vel_z=(fixed_ang_z, fixed_ang_z),
heading=None, heading=None,
), ),
debug_vis=True,
) )
env_cfg.commands.base_velocity = fixed_cfg env_cfg.commands.base_velocity = fixed_cfg

View File

@@ -12,7 +12,7 @@ from isaaclab.assets.articulation import ArticulationCfg
from isaaclab.utils import configclass from isaaclab.utils import configclass
from robot_lab.assets import ISAACLAB_ASSETS_DATA_DIR from robot_lab.assets import ISAACLAB_ASSETS_DATA_DIR
from robot_lab.assets.unitree_actuator import UnitreeActuatorCfg_Go2HV from robot_lab.assets.unitree_actuator import UnitreeActuatorCfg_Go1, UnitreeActuatorCfg_Go2HV
## ##
# Configuration # Configuration
@@ -158,3 +158,40 @@ GO2_CFG_UNITREE = UnitreeArticulationCfg(
], ],
# fmt: on # fmt: on
) )
# Go1 uses the complete Unitree URDF and the joint order used by the Unitree SDK.
GO1_CFG_UNITREE = UnitreeArticulationCfg(
spawn=UnitreeUrdfFileCfg(
asset_path=f"{ISAACLAB_ASSETS_DATA_DIR}/go1/urdf/go1.urdf",
),
init_state=ArticulationCfg.InitialStateCfg(
pos=(0.0, 0.0, 0.34),
joint_pos={
".*R_hip_joint": -0.1,
".*L_hip_joint": 0.1,
"F[L,R]_thigh_joint": 0.8,
"R[L,R]_thigh_joint": 1.0,
".*_calf_joint": -1.5,
},
joint_vel={".*": 0.0},
),
actuators={
"GO1": UnitreeActuatorCfg_Go1(
joint_names_expr=[".*"],
stiffness=28.0,
damping=0.7,
friction=0.01,
min_delay=0,
max_delay=4,
),
},
# fmt: off
joint_sdk_names=[
"FR_hip_joint", "FR_thigh_joint", "FR_calf_joint",
"FL_hip_joint", "FL_thigh_joint", "FL_calf_joint",
"RR_hip_joint", "RR_thigh_joint", "RR_calf_joint",
"RL_hip_joint", "RL_thigh_joint", "RL_calf_joint",
],
# fmt: on
)

View File

@@ -128,3 +128,17 @@ class UnitreeActuatorCfg_Go2HV(UnitreeActuatorCfg):
Y1 = 20.2 Y1 = 20.2
Y2 = 23.4 Y2 = 23.4
@configclass
class UnitreeActuatorCfg_Go1(UnitreeActuatorCfg):
"""Go1 actuator using the URDF effort limit.
Public Go1 torque-speed knee measurements are not provided with the asset,
so this configuration intentionally applies a constant 33.5 Nm limit
instead of borrowing the materially different Go2-HV motor curve.
"""
X1 = 1.0e9
X2 = 1.0e9
Y1 = 33.5
Y2 = 33.5

View File

@@ -0,0 +1,22 @@
# Copyright (c) 2024-2025 Ziqi Fan
# SPDX-License-Identifier: Apache-2.0
"""Go1 locomotion task registration."""
import gymnasium as gym
from isaaclab_tasks.utils import import_packages
gym.register(
id="RobotLab-Go1-v0",
entry_point="robot_lab.tasks.go1.env.go1_env:Go1Env",
disable_env_checker=True,
kwargs={
"env_cfg_entry_point": f"{__name__}.env_cfg:Go1EnvCfg",
"rsl_rl_cfg_entry_point": f"{__name__}.rsl_rl_cfg:MoECTSRunnerCfg",
},
)
_BLACKLIST_PKGS = ["utils"]
import_packages(__name__, _BLACKLIST_PKGS)

View File

@@ -0,0 +1 @@
"""Go1 environment implementation."""

View File

@@ -0,0 +1,14 @@
from isaaclab.envs import ManagerBasedRLEnv, ManagerBasedRLEnvCfg
from robot_lab.tasks.go2.manager.action_manager import ActionManagerGo2
class Go1Env(ManagerBasedRLEnv):
"""Go1 environment using the shared ordered action manager."""
cfg: ManagerBasedRLEnvCfg
def load_managers(self):
super().load_managers()
self.action_manager = ActionManagerGo2(self.cfg.actions, self)
print("[Go1Env-INFO] Using ordered action manager:", self.action_manager)

View File

@@ -0,0 +1,509 @@
import math
import isaaclab.sim as sim_utils
from isaaclab.assets import ArticulationCfg, AssetBaseCfg
from isaaclab.envs import ManagerBasedRLEnvCfg
from isaaclab.managers import CurriculumTermCfg as CurrTerm
from isaaclab.managers import EventTermCfg as EventTerm
from isaaclab.managers import ObservationGroupCfg as ObsGroup
from isaaclab.managers import ObservationTermCfg as ObsTerm
from isaaclab.managers import RewardTermCfg as RewTerm
from isaaclab.managers import SceneEntityCfg
from isaaclab.managers import TerminationTermCfg as DoneTerm
from isaaclab.scene import InteractiveSceneCfg
from isaaclab.sensors import ContactSensorCfg, RayCasterCfg, patterns
from isaaclab.terrains import TerrainImporterCfg
from isaaclab.utils import configclass
from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR, ISAACLAB_NUCLEUS_DIR
from isaaclab.utils.noise import AdditiveUniformNoiseCfg as Unoise
import robot_lab.tasks.go2.mdp as mdp
from robot_lab.assets.unitree import GO1_CFG_UNITREE
from robot_lab.tasks.go2.mdp.terrains import TERRAIN_CFG
JOINT_NAMES = [
"FR_hip_joint", "FR_thigh_joint", "FR_calf_joint",
"FL_hip_joint", "FL_thigh_joint", "FL_calf_joint",
"RR_hip_joint", "RR_thigh_joint", "RR_calf_joint",
"RL_hip_joint", "RL_thigh_joint", "RL_calf_joint",
]
BASE_LINK_NAME = "base"
FOOT_LINK_NAME = ".*_foot"
BASE_HEIGHT_TARGET = 0.30 # Go1 nominal trunk height used by the original Gym task.
##
# Scene definition
##
@configclass
class Go1SceneCfg(InteractiveSceneCfg):
"""Configuration for the terrain scene with the Go1 robot."""
terrain = TerrainImporterCfg(
prim_path="/World/ground",
terrain_type="generator",
terrain_generator=TERRAIN_CFG,
max_init_terrain_level=5,
collision_group=-1,
physics_material=sim_utils.RigidBodyMaterialCfg(
friction_combine_mode="average",
restitution_combine_mode="average",
static_friction=1.0,
dynamic_friction=1.0,
restitution=0.0,
),
visual_material=sim_utils.MdlFileCfg(
mdl_path=f"{ISAACLAB_NUCLEUS_DIR}/Materials/TilesMarbleSpiderWhiteBrickBondHoned/TilesMarbleSpiderWhiteBrickBondHoned.mdl",
project_uvw=True,
texture_scale=(0.25, 0.25),
),
debug_vis=False
)
robot: ArticulationCfg = GO1_CFG_UNITREE.replace(prim_path="{ENV_REGEX_NS}/Robot")
height_scanner = RayCasterCfg(
prim_path="{ENV_REGEX_NS}/Robot/base",
offset=RayCasterCfg.OffsetCfg(pos=(0.0, 0.0, 20.0)),
ray_alignment="yaw",
pattern_cfg=patterns.GridPatternCfg(resolution=0.1, size=[1.6, 1.0]),
debug_vis=False,
mesh_prim_paths=["/World/ground"],
)
height_scanner_small = RayCasterCfg(
prim_path="{ENV_REGEX_NS}/Robot/base",
offset=RayCasterCfg.OffsetCfg(pos=(0.0, 0.0, 20.0)),
ray_alignment="yaw",
pattern_cfg=patterns.GridPatternCfg(resolution=0.1, size=[0.4, 0.3]),
debug_vis=False,
mesh_prim_paths=["/World/ground"],
)
contact_forces = ContactSensorCfg(
prim_path="{ENV_REGEX_NS}/Robot/.*",
history_length=3,
track_air_time=True,
)
# 灯光
sky_light = AssetBaseCfg(
prim_path="/World/skyLight",
spawn=sim_utils.DomeLightCfg(
intensity=750.0,
texture_file=f"{ISAAC_NUCLEUS_DIR}/Materials/Textures/Skies/PolyHaven/kloofendal_43d_clear_puresky_4k.hdr",
),
)
##
# MDP settings
##
@configclass
class CommandsCfg:
"""Command specifications for the MDP."""
base_velocity = mdp.Go2RLGymCommandCfg()
@configclass
class ActionsCfg:
"""Action specifications for the MDP."""
# 腿部关节:位置控制
joint_pos = mdp.JointPositionActionCfg(
asset_name="robot",
joint_names=JOINT_NAMES,
scale={".*_hip_joint": 0.25, "^(?!.*_hip_joint).*": 0.25},
use_default_offset=True,
clip={".*": (-100.0, 100.0)},
preserve_order=True
)
@configclass
class ObservationsCfg:
@configclass
class PolicyCfg(ObsGroup):
"""Observations for policy group."""
base_ang_vel = ObsTerm(
func=mdp.base_ang_vel,
noise=Unoise(n_min=-0.2, n_max=0.2),
clip=(-100.0, 100.0),
scale=0.25,
)
projected_gravity = ObsTerm(
func=mdp.projected_gravity,
noise=Unoise(n_min=-0.05, n_max=0.05),
clip=(-100.0, 100.0),
scale=1.0,
)
velocity_commands = ObsTerm(
func=mdp.generated_commands,
params={"command_name": "base_velocity"},
clip=(-100.0, 100.0),
scale=1.0,
)
joint_pos = ObsTerm(
func=mdp.joint_pos_rel,
params={"asset_cfg": SceneEntityCfg("robot", joint_names=JOINT_NAMES, preserve_order=True)},
noise=Unoise(n_min=-0.03, n_max=0.03),
clip=(-100.0, 100.0),
scale=1.0,
)
joint_vel = ObsTerm(
func=mdp.joint_vel_rel,
params={"asset_cfg": SceneEntityCfg("robot", joint_names=JOINT_NAMES, preserve_order=True)},
noise=Unoise(n_min=-2.0, n_max=2.0),
clip=(-100.0, 100.0),
scale=0.05,
)
actions = ObsTerm(
func=mdp.last_action,
clip=(-100.0, 100.0),
scale=1.0,
)
def __post_init__(self):
self.history_length = 10
self.enable_corruption = True
self.concatenate_terms = True
self.flatten_history_dim = True
@configclass
class CriticCfg(ObsGroup):
base_lin_vel = ObsTerm(
func=mdp.base_lin_vel,
clip=(-100.0, 100.0),
scale=2.0,
)
base_ang_vel = ObsTerm(
func=mdp.base_ang_vel,
clip=(-100.0, 100.0),
scale=0.25,
)
projected_gravity = ObsTerm(
func=mdp.projected_gravity,
clip=(-100.0, 100.0),
scale=1.0,
)
velocity_commands = ObsTerm(
func=mdp.generated_commands,
params={"command_name": "base_velocity"},
clip=(-100.0, 100.0),
scale=1.0,
)
joint_pos = ObsTerm(
func=mdp.joint_pos_rel,
params={"asset_cfg": SceneEntityCfg("robot", joint_names=JOINT_NAMES, preserve_order=True)},
clip=(-100.0, 100.0),
scale=1.0,
)
joint_vel = ObsTerm(
func=mdp.joint_vel_rel,
params={"asset_cfg": SceneEntityCfg("robot", joint_names=JOINT_NAMES, preserve_order=True)},
clip=(-100.0, 100.0),
scale=0.05,
)
actions = ObsTerm(
func=mdp.last_action,
clip=(-100.0, 100.0),
scale=1.0,
)
joint_acc = ObsTerm(
func=mdp.joint_acc,
params={"asset_cfg": SceneEntityCfg("robot", joint_names=JOINT_NAMES, preserve_order=True)},
clip=(-100.0, 100.0),
scale=1e-4,
)
joint_torque = ObsTerm(
func=mdp.joint_effort,
params={"asset_cfg": SceneEntityCfg("robot", joint_names=JOINT_NAMES, preserve_order=True)},
clip=(-100.0, 100.0),
scale=0.01,
)
contact_force = ObsTerm(
func=mdp.foot_contact_force_norm,
params={"sensor_cfg": SceneEntityCfg("contact_forces", body_names=FOOT_LINK_NAME)},
clip=(-100.0, 100.0),
scale=1e-3,
)
height_scan = ObsTerm(
func=mdp.height_scan,
params={"sensor_cfg": SceneEntityCfg("height_scanner")},
clip=(-1.0, 1.0),
scale=2.5,
)
def __post_init__(self):
self.enable_corruption = False
self.concatenate_terms = True
@configclass
class SingleObsCfg(PolicyCfg):
def __post_init__(self):
super().__post_init__()
self.history_length = 1
policy: PolicyCfg = PolicyCfg()
critic: CriticCfg = CriticCfg()
single_obs: SingleObsCfg = SingleObsCfg() # Used to obtain the current-timestep observation for the MoE CTS model
@configclass
class EventCfg:
"""Configuration for events."""
randomize_rigid_body_mass_base = EventTerm(
func=mdp.randomize_rigid_body_mass,
mode="startup",
params={
"asset_cfg": SceneEntityCfg("robot", body_names=BASE_LINK_NAME),
"mass_distribution_params": (-1.0, 1.0),
"operation": "add",
"recompute_inertia": True,
},
)
randomize_rigid_body_mass_others = EventTerm(
func=mdp.randomize_rigid_body_mass,
mode="startup",
params={
"asset_cfg": SceneEntityCfg("robot", body_names="^(?!.*base).*"),
"mass_distribution_params": (0.9, 1.1),
"operation": "scale",
"recompute_inertia": True,
},
)
randomize_com_positions = EventTerm(
func=mdp.randomize_rigid_body_com,
mode="startup",
params={
"asset_cfg": SceneEntityCfg("robot", body_names=BASE_LINK_NAME),
"com_range": {"x": (-0.03, 0.03), "y": (-0.03, 0.03), "z": (-0.03, 0.03)},
},
)
reset_robot_joints = EventTerm(
func=mdp.reset_joints_by_scale,
mode="reset",
params={
"position_range": (0.5, 1.5),
"velocity_range": (0.0, 0.0),
},
)
randomize_actuator_gains = EventTerm(
func=mdp.randomize_actuator_gains,
mode="reset",
params={
"asset_cfg": SceneEntityCfg("robot", joint_names=".*"),
"stiffness_distribution_params": (0.9, 1.1),
"damping_distribution_params": (0.9, 1.1),
"operation": "scale",
"distribution": "uniform",
},
)
randomize_motor_zero_offset = EventTerm(
func=mdp.randomize_action_joint_pos_offset,
mode="reset",
params={
"action_term_name": "joint_pos",
"offset_range": (-0.035, 0.035),
},
)
randomize_push_robot = EventTerm(
func=mdp.push_by_setting_velocity,
mode="interval",
interval_range_s=(4.0, 4.0),
params={
"velocity_range": {
"x": (-0.4, 0.4),
"y": (-0.4, 0.4),
"roll": (-0.6, 0.6),
"pitch": (-0.6, 0.6),
"yaw": (-0.6, 0.6)
}
}
)
randomize_rigid_body_material = EventTerm(
func=mdp.randomize_rigid_body_material,
mode="startup",
params={
"asset_cfg": SceneEntityCfg("robot", body_names=".*"),
"static_friction_range": (0.0, 2.0),
"dynamic_friction_range": (0.0, 2.0),
"restitution_range": (0.0, 0.5),
"num_buckets": 64,
"make_consistent": True
},
)
reset_base = EventTerm(
func=mdp.reset_root_state_uniform,
mode="reset",
params={
"pose_range": {"x": (-0.5, 0.5), "y": (-0.5, 0.5), "z": (0.0, 0.2), "yaw": (-3.14, 3.14)},
"velocity_range": {
"x": (-0.5, 0.5),
"y": (-0.5, 0.5),
"z": (-0.5, 0.5),
"roll": (-0.5, 0.5),
"pitch": (-0.5, 0.5),
"yaw": (-0.5, 0.5),
},
},
)
@configclass
class RewardsCfg:
"""Reward terms for the MDP."""
track_lin_vel_xy_exp = RewTerm(
func=mdp.track_lin_vel_xy_exp,
weight=2.0,
params={"command_name": "base_velocity", "std": 0.5}
)
track_ang_vel_z_exp = RewTerm(
func=mdp.track_ang_vel_z_exp,
weight=1.0,
params={"command_name": "base_velocity", "std": 0.5}
)
lin_vel_z_l2 = RewTerm(func=mdp.lin_vel_z_l2, weight=-2.0)
ang_vel_xy_l2 = RewTerm(func=mdp.ang_vel_xy_l2, weight=-0.05)
# The joint_acc reward is not computed on the same scale in Gym and Lab.
# In Gym, it is computed at the policy-step level,
# while in Lab, it is computed at the physics-step level.
# In Lab, the reward calculation is more precise, and because the L2 term is more sensitive to outliers.
# Thus, the reward value is overall higher, so we need to decrease the weights to be suitable for Lab.
joint_acc_l2 = RewTerm(
func=mdp.joint_acc_l2,
weight=-1.0e-7,
params={"asset_cfg": SceneEntityCfg("robot", joint_names=JOINT_NAMES)}
)
joint_power = RewTerm(
func=mdp.joint_power,
weight=-2e-5,
params={"asset_cfg": SceneEntityCfg("robot", joint_names=JOINT_NAMES)}
)
joint_torques_l2 = RewTerm(
func=mdp.joint_torques_l2,
weight=-1e-4,
params={"asset_cfg": SceneEntityCfg("robot", joint_names=JOINT_NAMES)}
)
base_height_l2 = RewTerm(
func=mdp.base_height_l2,
weight=-1.0,
params={
"asset_cfg": SceneEntityCfg("robot", body_names=BASE_LINK_NAME),
"target_height": BASE_HEIGHT_TARGET,
"sensor_cfg": SceneEntityCfg("height_scanner_small"),
}
)
action_rate_l2 = RewTerm(func=mdp.action_rate_l2, weight=-0.01)
action_smoothness_l2 = RewTerm(func=mdp.action_smoothness_l2, weight=-0.01)
undesired_contacts = RewTerm(
func=mdp.undesired_contacts,
weight=-1.0,
params={"sensor_cfg": SceneEntityCfg("contact_forces", body_names=".*_thigh|.*_calf"), "threshold": 5.0},
)
joint_pos_limits = RewTerm(
func=mdp.joint_pos_limits,
weight=-2.0,
params={"asset_cfg": SceneEntityCfg("robot", joint_names=JOINT_NAMES)},
)
feet_regulation = RewTerm(
func=mdp.feet_regulation,
weight=-0.05,
params={
"base_height_target": BASE_HEIGHT_TARGET,
"asset_cfg": SceneEntityCfg("robot", body_names=FOOT_LINK_NAME),
"sensor_cfg": SceneEntityCfg("height_scanner_small"),
},
)
hip_pos_penalty_l1 = RewTerm(
func=mdp.hip_pos_penalty_l1,
weight=-0.05,
params={
"command_name": "base_velocity",
"asset_cfg": SceneEntityCfg("robot", joint_names=".*_hip_joint"),
"stand_still_scale": 1.0,
"command_threshold": 0.1,
},
)
joint_pos_penalty_l1 = RewTerm(
func=mdp.joint_pos_penalty_l1,
weight=-0.01,
params={
"command_name": "base_velocity",
"asset_cfg": SceneEntityCfg("robot", joint_names=".*_(thigh|calf)_joint"),
"stand_still_scale": 1.0,
"velocity_threshold": 0.1,
"command_threshold": 0.1,
},
)
@configclass
class TerminationsCfg:
"""Termination terms for the MDP."""
time_out = DoneTerm(func=mdp.time_out, time_out=True)
illegal_contact = DoneTerm(
func=mdp.illegal_contact,
params={
"sensor_cfg": SceneEntityCfg("contact_forces", body_names=BASE_LINK_NAME),
"threshold": 1.0
},
)
@configclass
class CurriculumCfg:
"""Curriculum terms for the MDP."""
terrain_levels = CurrTerm(func=mdp.terrain_levels_vel_gym)
base_linear_velocity = CurrTerm(mdp.gradual_reward_weight_modification, params={
"term_name": "lin_vel_z_l2", "initial_weight": -2.0, "final_weight": -0.0, "start_it": 0, "end_it": 1500
})
base_height_l2 = CurrTerm(mdp.gradual_reward_weight_modification, params={
"term_name": "base_height_l2", "initial_weight": -1.0, "final_weight": -10.0, "start_it": 0, "end_it": 5000
})
##
# Environment configuration
##
@configclass
class Go1EnvCfg(ManagerBasedRLEnvCfg):
"""Merged configuration for the Go1 robot on rough terrain."""
# Scene settings
scene: Go1SceneCfg = Go1SceneCfg(num_envs=4096, env_spacing=0.5)
# Basic settings
observations: ObservationsCfg = ObservationsCfg()
actions: ActionsCfg = ActionsCfg()
commands: CommandsCfg = CommandsCfg()
# MDP settings
rewards: RewardsCfg = RewardsCfg()
terminations: TerminationsCfg = TerminationsCfg()
events: EventCfg = EventCfg()
curriculum: CurriculumCfg = CurriculumCfg()
def __post_init__(self):
"""Post initialization."""
# General settings
self.decimation = 4
self.episode_length_s = 25.0
# Simulation settings
self.sim.dt = 0.005
self.sim.render_interval = self.decimation
# Physics material settings from subclass
self.sim.physics_material = self.scene.terrain.physics_material
self.sim.physx.gpu_max_rigid_patch_count = int(1 * 1024 * 1024) # 1 million
self.sim.physx.gpu_collision_stack_size = int(128 * 1024 * 1024) # 128 MB
self.sim.physx.enable_external_forces_every_iteration = True
# Update sensor periods
if self.scene.height_scanner is not None:
self.scene.height_scanner.update_period = self.decimation * self.sim.dt
if self.scene.height_scanner_small is not None:
self.scene.height_scanner_small.update_period = self.decimation * self.sim.dt
if self.scene.contact_forces is not None:
self.scene.contact_forces.update_period = self.sim.dt
# Handle curriculum for terrain generator
if getattr(self.curriculum, "terrain_levels", None) is not None:
if self.scene.terrain.terrain_generator is not None:
self.scene.terrain.terrain_generator.curriculum = True
else:
if self.scene.terrain.terrain_generator is not None:
self.scene.terrain.terrain_generator.curriculum = False

View File

@@ -0,0 +1,86 @@
from isaaclab.utils import configclass
from isaaclab_rl.rsl_rl import RslRlOnPolicyRunnerCfg, RslRlPpoActorCriticCfg, RslRlPpoAlgorithmCfg
@configclass
class PPORunnerCfg(RslRlOnPolicyRunnerCfg):
num_steps_per_env = 24
max_iterations = 300000
save_interval = 500
experiment_name = "go1_rough"
policy = RslRlPpoActorCriticCfg(
init_noise_std=1.0,
actor_obs_normalization=False,
critic_obs_normalization=False,
actor_hidden_dims=[512, 256, 128],
critic_hidden_dims=[512, 256, 128],
activation="elu",
)
algorithm = RslRlPpoAlgorithmCfg(
value_loss_coef=1.0,
use_clipped_value_loss=True,
clip_param=0.2,
entropy_coef=0.01,
num_learning_epochs=5,
num_mini_batches=4,
learning_rate=1.0e-3,
schedule="adaptive",
gamma=0.99,
lam=0.95,
desired_kl=0.01,
max_grad_norm=1.0,
)
@configclass
class RslRlMoeCtsActorCriticCfg(RslRlPpoActorCriticCfg):
class_name = "ActorCriticMoECTS"
init_noise_std = 1.0
expert_num = 8 # number of experts in the student model
latent_dim = 32
norm_type = 'l2norm' # normalization type for encoders: l2norm, simnorm
teacher_encoder_hidden_dims = [512, 256]
student_encoder_hidden_dims = [512, 256, 256]
actor_hidden_dims=[512, 256, 128]
critic_hidden_dims=[512, 256, 128]
activation="elu"
actor_obs_normalization = False
critic_obs_normalization = False
@configclass
class RslRlMoeCtsAlgorithmCfg(RslRlPpoAlgorithmCfg):
class_name = "MoECTS"
value_loss_coef = 1.0
load_balance_coef = 0.01 # coefficient for load balance loss
use_clipped_value_loss = True
clip_param = 0.2
entropy_coef = 0.01
num_learning_epochs = 5
num_mini_batches = 4
learning_rate = 1e-3
student_encoder_learning_rate = 1e-3
schedule = "adaptive"
gamma = 0.99
lam = 0.95
betas = (0.9, 0.999)
weight_decay = 0.0
desired_kl = 0.01
max_grad_norm = 1.0
teacher_env_ratio = 0.75 # percentage of envs assigned to teacher
@configclass
class MoECTSRunnerCfg(RslRlOnPolicyRunnerCfg):
experiment_name = "go1_moe_cts"
class_name = "OnPolicyRunnerCTS"
num_steps_per_env = 24
max_iterations = 300000
save_interval = 500
policy = RslRlMoeCtsActorCriticCfg()
algorithm = RslRlMoeCtsAlgorithmCfg()
# concat elu inspired by concat relu from https://arxiv.org/pdf/2303.07507
@configclass
class MoECTSCatELURunnerCfg(MoECTSRunnerCfg):
def __post_init__(self):
super().__post_init__()
self.policy.activation = 'cat_elu'

View File

@@ -19,8 +19,8 @@ from isaaclab_tasks.utils import import_packages
## ##
gym.register( gym.register(
id="RobotLab-Go2-v0", id="RobotLab-Go2-v0",
# entry_point="robot_lab.tasks.go2.env.go2_env:Go2Env", entry_point="robot_lab.tasks.go2.env.go2_env:Go2Env",
entry_point="robot_lab.tasks.go2.env.go2_env:ActionDelayGo2Env", # entry_point="robot_lab.tasks.go2.env.go2_env:ActionDelayGo2Env", # using motor-level delay, so disabled env-level delay
disable_env_checker=True, disable_env_checker=True,
kwargs={ kwargs={
"env_cfg_entry_point": f"{__name__}.env_cfg:Go2EnvCfg", "env_cfg_entry_point": f"{__name__}.env_cfg:Go2EnvCfg",

View File

@@ -60,7 +60,7 @@ class Go2SceneCfg(InteractiveSceneCfg):
debug_vis=False debug_vis=False
) )
robot: ArticulationCfg = GO2_CFG_ROBOTLAB.replace(prim_path="{ENV_REGEX_NS}/Robot") robot: ArticulationCfg = GO2_CFG_UNITREE.replace(prim_path="{ENV_REGEX_NS}/Robot")
height_scanner = RayCasterCfg( height_scanner = RayCasterCfg(
prim_path="{ENV_REGEX_NS}/Robot/base", prim_path="{ENV_REGEX_NS}/Robot/base",
@@ -159,7 +159,7 @@ class ObservationsCfg:
scale=1.0, scale=1.0,
) )
def __post_init__(self): def __post_init__(self):
self.history_length = 5 self.history_length = 10
self.enable_corruption = True self.enable_corruption = True
self.concatenate_terms = True self.concatenate_terms = True
self.flatten_history_dim = True self.flatten_history_dim = True
@@ -350,12 +350,12 @@ class RewardsCfg:
track_lin_vel_xy_exp = RewTerm( track_lin_vel_xy_exp = RewTerm(
func=mdp.track_lin_vel_xy_exp, func=mdp.track_lin_vel_xy_exp,
weight=1.0, weight=2.0,
params={"command_name": "base_velocity", "std": 0.5} params={"command_name": "base_velocity", "std": 0.5}
) )
track_ang_vel_z_exp = RewTerm( track_ang_vel_z_exp = RewTerm(
func=mdp.track_ang_vel_z_exp, func=mdp.track_ang_vel_z_exp,
weight=0.5, weight=1.0,
params={"command_name": "base_velocity", "std": 0.5} params={"command_name": "base_velocity", "std": 0.5}
) )
lin_vel_z_l2 = RewTerm(func=mdp.lin_vel_z_l2, weight=-2.0) lin_vel_z_l2 = RewTerm(func=mdp.lin_vel_z_l2, weight=-2.0)
@@ -466,7 +466,7 @@ class Go2EnvCfg(ManagerBasedRLEnvCfg):
"""Merged configuration for the Go2 robot on rough terrain.""" """Merged configuration for the Go2 robot on rough terrain."""
# Scene settings # Scene settings
scene: Go2SceneCfg = Go2SceneCfg(num_envs=8192, env_spacing=0.5) scene: Go2SceneCfg = Go2SceneCfg(num_envs=16384, env_spacing=0.5)
# Basic settings # Basic settings
observations: ObservationsCfg = ObservationsCfg() observations: ObservationsCfg = ObservationsCfg()
actions: ActionsCfg = ActionsCfg() actions: ActionsCfg = ActionsCfg()

View File

@@ -26,7 +26,7 @@ from __future__ import annotations # For forward reference of type hints
from typing import TYPE_CHECKING, Sequence from typing import TYPE_CHECKING, Sequence
if TYPE_CHECKING: # Avoid circular import for type checking if TYPE_CHECKING: # Avoid circular import for type checking
from robot_lab.tasks.go2.env.go2_env import ActionDelayGo2Env from robot_lab.tasks.go2.env.go2_env import Go2Env
from itertools import product from itertools import product
@@ -44,9 +44,9 @@ from robot_lab.tasks.go2.mdp.utils import is_robot_on_terrain, sample_disjoint_i
class Go2RLGymCommand(CommandTerm): class Go2RLGymCommand(CommandTerm):
cfg: Go2RLGymCommandCfg cfg: Go2RLGymCommandCfg
_env: ActionDelayGo2Env _env: Go2Env
def __init__(self, cfg: Go2RLGymCommandCfg, env: ActionDelayGo2Env): def __init__(self, cfg: Go2RLGymCommandCfg, env: Go2Env):
"""Reference: https://github.com/wty-yy/go2_rl_gym/blob/master/legged_gym/envs/base/legged_robot.py """Reference: https://github.com/wty-yy/go2_rl_gym/blob/master/legged_gym/envs/base/legged_robot.py
LeggedRobot._resample_command() and LeggedRobot._post_physics_step_callback() LeggedRobot._resample_command() and LeggedRobot._post_physics_step_callback()
""" """
@@ -107,9 +107,12 @@ class Go2RLGymCommand(CommandTerm):
self.metrics["max_command_x"] = self.max_command_x self.metrics["max_command_x"] = self.max_command_x
def reset(self, env_ids: Sequence[int] | None = None): def reset(self, env_ids: Sequence[int] | None = None):
if env_ids is None:
env_ids = torch.arange(self.num_envs, device=self.device)
self.time_left[env_ids] = self.cfg.resampling_time self.time_left[env_ids] = self.cfg.resampling_time
self.commands_xy_accumulation[env_ids] = 0.0 self.commands_xy_accumulation[env_ids] = 0.0
self.max_move_distance[env_ids] = 0.0 self.max_move_distance[env_ids] = 0.0
self.last_is_limit_vel[env_ids] = False
return super().reset(env_ids) return super().reset(env_ids)
def _resample(self, env_ids: Sequence[int]): def _resample(self, env_ids: Sequence[int]):

View File

@@ -178,7 +178,7 @@ TERRAIN_CFG = Go2TerrainGeneratorCfg(
# slope correction = 0.75 ~ 36.9 degrees by default, # slope correction = 0.75 ~ 36.9 degrees by default,
# but recommended to set for each terrain type separately using with_slope_threshold # but recommended to set for each terrain type separately using with_slope_threshold
slope_threshold=0.75, slope_threshold=0.75,
use_gym_difficulty=True, use_gym_difficulty=False,
use_cache=False, use_cache=False,
sub_terrains={ sub_terrains={
"wave": with_slope_threshold( "wave": with_slope_threshold(

View File

@@ -233,9 +233,12 @@ class MoECTS:
# RND loss # RND loss
mean_rnd_loss = 0 if self.rnd else None mean_rnd_loss = 0 if self.rnd else None
# Get mini batch generator # Reuse the exact same shuffled samples for both update phases without
generator = self.storage.mini_batch_generator(self.num_mini_batches, self.num_learning_epochs) # materializing every epoch and mini-batch on the GPU at once.
data = list(generator) batch_indices = self.storage.generate_mini_batch_indices()
generator = self.storage.mini_batch_generator(
self.num_mini_batches, self.num_learning_epochs, batch_indices=batch_indices
)
# Iterate over batches # Iterate over batches
teacher_samples = self.teacher_num_envs * self.storage.num_transitions_per_env // self.num_mini_batches teacher_samples = self.teacher_num_envs * self.storage.num_transitions_per_env // self.num_mini_batches
@@ -251,7 +254,7 @@ class MoECTS:
old_sigma_batch, old_sigma_batch,
hidden_states_batch, hidden_states_batch,
masks_batch, masks_batch,
) in data: ) in generator:
original_batch_size = obs_batch.batch_size[0] original_batch_size = obs_batch.batch_size[0]
# Check if we should normalize advantages per mini batch # Check if we should normalize advantages per mini batch
@@ -377,6 +380,9 @@ class MoECTS:
if mean_rnd_loss is not None: if mean_rnd_loss is not None:
mean_rnd_loss += rnd_loss.item() mean_rnd_loss += rnd_loss.item()
generator = self.storage.mini_batch_generator(
self.num_mini_batches, self.num_learning_epochs, batch_indices=batch_indices
)
for ( for (
obs_batch, obs_batch,
actions_batch, actions_batch,
@@ -388,7 +394,7 @@ class MoECTS:
old_sigma_batch, old_sigma_batch,
hidden_states_batch, hidden_states_batch,
masks_batch, masks_batch,
) in data: ) in generator:
# Student encoder loss # Student encoder loss
obs_a_batch = self.policy.get_actor_obs(obs_batch) obs_a_batch = self.policy.get_actor_obs(obs_batch)
obs_a_batch = self.policy.actor_obs_normalizer(obs_a_batch) obs_a_batch = self.policy.actor_obs_normalizer(obs_a_batch)

View File

@@ -83,6 +83,7 @@ class OnPolicyRunnerCTS:
from robogauge.scripts.client import RoboGaugeClient from robogauge.scripts.client import RoboGaugeClient
self.robogauge_client = RoboGaugeClient(f"http://127.0.0.1:{robogauge_cfg.get('port', 9973)}") self.robogauge_client = RoboGaugeClient(f"http://127.0.0.1:{robogauge_cfg.get('port', 9973)}")
self.robogauge_client.wait_until_available()
except Exception as e: except Exception as e:
print(f"[INFO] RoboGauge client could not be initialized: {e}, disabling RoboGauge interface.") print(f"[INFO] RoboGauge client could not be initialized: {e}, disabling RoboGauge interface.")
self.robogauge_client = None self.robogauge_client = None

View File

@@ -127,7 +127,25 @@ class RolloutStorageCTS:
yield self.observations[i], self.actions[i], self.privileged_actions[i], self.dones[i] yield self.observations[i], self.actions[i], self.privileged_actions[i], self.dones[i]
# For reinforcement learning with feedforward networks # For reinforcement learning with feedforward networks
def mini_batch_generator(self, num_mini_batches: int, num_epochs: int = 8) -> Generator: def generate_mini_batch_indices(self) -> tuple[torch.Tensor, torch.Tensor]:
"""Generate the teacher and student permutations shared by both update phases."""
if self.training_type != "rl":
raise ValueError("This function is only available for reinforcement learning training.")
teacher_samples_num = self.teacher_num_envs * self.num_transitions_per_env
student_samples_num = self.student_num_envs * self.num_transitions_per_env
teacher_indices = torch.randperm(teacher_samples_num, requires_grad=False, device=self.device)
student_indices = teacher_samples_num + torch.randperm(
student_samples_num, requires_grad=False, device=self.device
)
return teacher_indices, student_indices
def mini_batch_generator(
self,
num_mini_batches: int,
num_epochs: int = 8,
batch_indices: tuple[torch.Tensor, torch.Tensor] | None = None,
) -> Generator:
if self.training_type != "rl": if self.training_type != "rl":
raise ValueError("This function is only available for reinforcement learning training.") raise ValueError("This function is only available for reinforcement learning training.")
@@ -136,8 +154,10 @@ class RolloutStorageCTS:
student_samples_num = self.student_num_envs * self.num_transitions_per_env student_samples_num = self.student_num_envs * self.num_transitions_per_env
teacher_mini_batch_size = teacher_samples_num // num_mini_batches teacher_mini_batch_size = teacher_samples_num // num_mini_batches
student_mini_batch_size = student_samples_num // num_mini_batches student_mini_batch_size = student_samples_num // num_mini_batches
teacher_indices = torch.randperm(teacher_samples_num, requires_grad=False, device=self.device) if batch_indices is None:
student_indices = teacher_samples_num + torch.randperm(student_samples_num, requires_grad=False, device=self.device) teacher_indices, student_indices = self.generate_mini_batch_indices()
else:
teacher_indices, student_indices = batch_indices
# Core # Core
observations = self.observations.transpose(0, 1).flatten(0, 1) observations = self.observations.transpose(0, 1).flatten(0, 1)