├── DwaQ_stairs.gif ├── legged_gym ├── .gitattributes ├── .github │ └── ISSUE_TEMPLATE │ │ └── bug_report.md ├── .gitignore ├── LICENSE ├── README.md ├── env_cfg.pkl ├── go1_gym_deploy │ ├── __init__.py │ ├── autostart │ │ ├── start_controller.sh │ │ └── start_unitree_sdk.sh │ ├── docker │ │ ├── Dockerfile │ │ ├── Makefile │ │ ├── unzip_image.sh │ │ └── zip_image.sh │ ├── envs │ │ ├── Saved_Models.zip │ │ ├── Saved_Models │ │ │ ├── actor_dwaq.pt │ │ │ ├── encoder_dwaq.pt │ │ │ ├── encoder_mu_dwaq.pt │ │ │ ├── encoder_var_dwaq.pt │ │ │ └── parameters.pkl │ │ ├── __init__.py │ │ ├── history_wrapper.py │ │ └── lcm_agent.py │ ├── installer │ │ └── install_deployment_code.sh │ ├── lcm_types │ │ ├── __init__.py │ │ ├── camera_message_lcmt.py │ │ ├── camera_message_rect_wide.py │ │ ├── leg_control_data_lcmt.lcm │ │ ├── leg_control_data_lcmt.py │ │ ├── pd_tau_targets_lcmt.lcm │ │ ├── pd_tau_targets_lcmt.py │ │ ├── rc_command_lcmt.lcm │ │ ├── rc_command_lcmt.py │ │ ├── state_estimator_lcmt.lcm │ │ └── state_estimator_lcmt.py │ ├── scripts │ │ ├── __init__.py │ │ ├── deploy_policy.py │ │ └── send_to_unitree.sh │ ├── setup.py │ ├── tests │ │ ├── __init__.py │ │ └── check_camera_msgs.py │ ├── unitree_legged_sdk_bin │ │ ├── __init__.py │ │ ├── lcm_position │ │ └── lcm_position.cpp │ └── utils │ │ ├── __init__.py │ │ ├── cheetah_state_estimator.py │ │ ├── command_profile.py │ │ ├── deployment_runner.py │ │ ├── logger.py │ │ └── network_config_unitree.py ├── legged_gym │ ├── __init__.py │ ├── envs │ │ ├── __init__.py │ │ ├── a1 │ │ │ └── a1_config.py │ │ ├── anymal_b │ │ │ └── anymal_b_config.py │ │ ├── anymal_c │ │ │ ├── anymal.py │ │ │ ├── flat │ │ │ │ └── anymal_c_flat_config.py │ │ │ └── mixed_terrains │ │ │ │ └── anymal_c_rough_config.py │ │ ├── base │ │ │ ├── base_config.py │ │ │ ├── base_task.py │ │ │ ├── legged_robot.py │ │ │ └── legged_robot_config.py │ │ ├── cassie │ │ │ ├── cassie.py │ │ │ └── cassie_config.py │ │ ├── go1 │ │ │ └── go1_config.py │ │ └── wrappers │ │ │ └── history_wrapper.py │ ├── scripts │ │ ├── play.py │ │ ├── stand_still.py │ │ └── train.py │ ├── tests │ │ └── test_env.py │ └── utils │ │ ├── __init__.py │ │ ├── helpers.py │ │ ├── logger.py │ │ ├── math.py │ │ ├── task_registry.py │ │ └── terrain.py ├── licenses │ ├── assets │ │ ├── ANYmal_b_license.txt │ │ ├── ANYmal_c_license.txt │ │ ├── a1_license.txt │ │ └── cassie_license.txt │ └── dependencies │ │ └── matplotlib_license.txt ├── resources │ ├── actuator_nets │ │ └── anydrive_v3_lstm.pt │ └── robots │ │ ├── a1 │ │ ├── a1_license.txt │ │ ├── meshes │ │ │ ├── calf.dae │ │ │ ├── hip.dae │ │ │ ├── thigh.dae │ │ │ ├── thigh_mirror.dae │ │ │ ├── trunk.dae │ │ │ └── trunk_A1.png │ │ └── urdf │ │ │ └── a1.urdf │ │ ├── anymal_b │ │ ├── ANYmal_b_license.txt │ │ ├── meshes │ │ │ ├── anymal_base.dae │ │ │ ├── anymal_foot.dae │ │ │ ├── anymal_hip_l.dae │ │ │ ├── anymal_hip_r.dae │ │ │ ├── anymal_shank_l.dae │ │ │ ├── anymal_shank_r.dae │ │ │ ├── anymal_thigh_l.dae │ │ │ ├── anymal_thigh_r.dae │ │ │ ├── base_uv_texture.jpg │ │ │ └── carbon_uv_texture.jpg │ │ └── urdf │ │ │ └── anymal_b.urdf │ │ ├── anymal_c │ │ ├── ANYmal_c_license.txt │ │ ├── meshes │ │ │ ├── base.dae │ │ │ ├── base.jpg │ │ │ ├── battery.dae │ │ │ ├── battery.jpg │ │ │ ├── bottom_shell.dae │ │ │ ├── bottom_shell.jpg │ │ │ ├── depth_camera.dae │ │ │ ├── depth_camera.jpg │ │ │ ├── drive.dae │ │ │ ├── drive.jpg │ │ │ ├── face.dae │ │ │ ├── face.jpg │ │ │ ├── foot.dae │ │ │ ├── foot.jpg │ │ │ ├── handle.dae │ │ │ ├── handle.jpg │ │ │ ├── hatch.dae │ │ │ ├── hatch.jpg │ │ │ ├── hip.jpg │ │ │ ├── hip_l.dae │ │ │ ├── hip_r.dae │ │ │ ├── lidar.dae │ │ │ ├── lidar.jpg │ │ │ ├── lidar_cage.dae │ │ │ ├── lidar_cage.jpg │ │ │ ├── remote.dae │ │ │ ├── remote.jpg │ │ │ ├── shank.jpg │ │ │ ├── shank_l.dae │ │ │ ├── shank_r.dae │ │ │ ├── thigh.dae │ │ │ ├── thigh.jpg │ │ │ ├── top_shell.dae │ │ │ ├── top_shell.jpg │ │ │ ├── wide_angle_camera.dae │ │ │ └── wide_angle_camera.jpg │ │ └── urdf │ │ │ └── anymal_c.urdf │ │ ├── cassie │ │ ├── cassie_license.txt │ │ ├── meshes │ │ │ ├── abduction.stl │ │ │ ├── abduction_mirror.stl │ │ │ ├── achilles-rod.stl │ │ │ ├── hip.stl │ │ │ ├── hip_mirror.stl │ │ │ ├── knee-output.stl │ │ │ ├── knee-output_mirror.stl │ │ │ ├── pelvis.stl │ │ │ ├── plantar-rod.stl │ │ │ ├── shin-bone.stl │ │ │ ├── shin-bone_mirror.stl │ │ │ ├── tarsus.stl │ │ │ ├── tarsus_mirror.stl │ │ │ ├── thigh.stl │ │ │ ├── thigh_mirror.stl │ │ │ ├── toe-output-crank.stl │ │ │ ├── toe.stl │ │ │ ├── toe_mirror.stl │ │ │ ├── torso.stl │ │ │ ├── yaw.stl │ │ │ └── yaw_mirror.stl │ │ └── urdf │ │ │ └── cassie.urdf │ │ └── go1 │ │ ├── meshes │ │ ├── calf.stl │ │ ├── hip.stl │ │ ├── thigh.stl │ │ ├── thigh_mirror.stl │ │ └── trunk.stl │ │ ├── urdf │ │ └── go1.urdf │ │ └── xml │ │ └── go1.xml ├── setup.py └── train_cfg.pkl ├── readme.md └── rsl_rl-1.0.2 ├── .gitignore ├── LICENSE ├── README.md ├── licenses └── dependencies │ ├── numpy_license.txt │ └── torch_license.txt ├── rsl_rl ├── __init__.py ├── algorithms │ ├── __init__.py │ └── ppo.py ├── env │ ├── __init__.py │ └── vec_env.py ├── modules │ ├── __init__.py │ ├── actor_critic.py │ ├── actor_critic_DWAQ.py │ └── actor_critic_recurrent.py ├── runners │ ├── __init__.py │ └── on_policy_runner.py ├── storage │ ├── __init__.py │ └── rollout_storage.py └── utils │ ├── __init__.py │ └── utils.py └── setup.py /DwaQ_stairs.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/DwaQ_stairs.gif -------------------------------------------------------------------------------- /legged_gym/.gitattributes: -------------------------------------------------------------------------------- 1 | *.dae filter=lfs diff=lfs merge=lfs -text 2 | *.obj filter=lfs diff=lfs merge=lfs -text 3 | *.obj text !filter !merge !diff 4 | *.dae text !filter !merge !diff 5 | -------------------------------------------------------------------------------- /legged_gym/.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: nikitardn 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Execute `./path/script arg1 arg2` 16 | 1. Then ... 17 | 1. See error: ... 18 | 19 | **Expected behavior** 20 | A clear and concise description of what you expected to happen. 21 | 22 | **System (please complete the following information):** 23 | - Commit: [e.g. 8f3b9ca] 24 | - OS: [e.g. Ubuntu 20.04] 25 | - GPU: [e.g. RTX 2060 Super] 26 | - CUDA: [e.g. 11.4] 27 | - GPU Driver: [e.g. 470.82.01] 28 | 29 | **Additional context** 30 | Add any other context about the problem here. 31 | -------------------------------------------------------------------------------- /legged_gym/.gitignore: -------------------------------------------------------------------------------- 1 | # These are some examples of commonly ignored file patterns. 2 | # You should customize this list as applicable to your project. 3 | # Learn more about .gitignore: 4 | # https://www.atlassian.com/git/tutorials/saving-changes/gitignore 5 | 6 | # Node artifact files 7 | node_modules/ 8 | dist/ 9 | 10 | # Compiled Java class files 11 | *.class 12 | 13 | # Compiled Python bytecode 14 | *.py[cod] 15 | 16 | # Log files 17 | *.log 18 | 19 | # Package files 20 | *.jar 21 | 22 | # Maven 23 | target/ 24 | dist/ 25 | 26 | # JetBrains IDE 27 | .idea/ 28 | 29 | # Unit test reports 30 | TEST*.xml 31 | 32 | # Generated by MacOS 33 | .DS_Store 34 | 35 | # Generated by Windows 36 | Thumbs.db 37 | 38 | # Applications 39 | *.app 40 | *.exe 41 | *.war 42 | 43 | # Large media files 44 | *.mp4 45 | *.tiff 46 | *.avi 47 | *.flv 48 | *.mov 49 | *.wmv 50 | 51 | # VS Code 52 | .vscode 53 | # logs 54 | logs 55 | runs 56 | 57 | # other 58 | *.egg-info 59 | __pycache__ -------------------------------------------------------------------------------- /legged_gym/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021, ETH Zurich, Nikita Rudin 2 | Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors 16 | may be used to endorse or promote products derived from this software without 17 | specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 23 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | See licenses/assets for license information for assets included in this repository. 31 | See licenses/dependencies for license information of dependencies of this package. 32 | -------------------------------------------------------------------------------- /legged_gym/README.md: -------------------------------------------------------------------------------- 1 | # Isaac Gym Environments for Legged Robots # 2 | This repository provides the environment used to train ANYmal (and other robots) to walk on rough terrain using NVIDIA's Isaac Gym. 3 | It includes all components needed for sim-to-real transfer: actuator network, friction & mass randomization, noisy observations and random pushes during training. 4 | 5 | **Maintainer**: Nikita Rudin 6 | **Affiliation**: Robotic Systems Lab, ETH Zurich 7 | **Contact**: rudinn@ethz.ch 8 | 9 | --- 10 | 11 | ### :bell: Announcement (09.01.2024) ### 12 | 13 | With the shift from Isaac Gym to Isaac Sim at NVIDIA, we have migrated all the environments from this work to [Orbit](https://github.com/NVIDIA-Omniverse/Orbit). Following this migration, this repository will receive limited updates and support. We encourage all users to migrate to the new framework for their applications. 14 | 15 | Information about this work's locomotion-related tasks in Orbit is available [here](https://isaac-orbit.github.io/orbit/source/features/environments.html#locomotion). 16 | 17 | --- 18 | 19 | ### Useful Links ### 20 | 21 | Project website: https://leggedrobotics.github.io/legged_gym/ 22 | Paper: https://arxiv.org/abs/2109.11978 23 | 24 | ### Installation ### 25 | 1. Create a new python virtual env with python 3.6, 3.7 or 3.8 (3.8 recommended) 26 | 2. Install pytorch 1.10 with cuda-11.3: 27 | - `pip3 install torch==1.10.0+cu113 torchvision==0.11.1+cu113 torchaudio==0.10.0+cu113 -f https://download.pytorch.org/whl/cu113/torch_stable.html` 28 | 3. Install Isaac Gym 29 | - Download and install Isaac Gym Preview 3 (Preview 2 will not work!) from https://developer.nvidia.com/isaac-gym 30 | - `cd isaacgym/python && pip install -e .` 31 | - Try running an example `cd examples && python 1080_balls_of_solitude.py` 32 | - For troubleshooting check docs `isaacgym/docs/index.html`) 33 | 4. Install rsl_rl (PPO implementation) 34 | - Clone https://github.com/leggedrobotics/rsl_rl 35 | - `cd rsl_rl && git checkout v1.0.2 && pip install -e .` 36 | 5. Install legged_gym 37 | - Clone this repository 38 | - `cd legged_gym && pip install -e .` 39 | 40 | ### CODE STRUCTURE ### 41 | 1. Each environment is defined by an env file (`legged_robot.py`) and a config file (`legged_robot_config.py`). The config file contains two classes: one containing all the environment parameters (`LeggedRobotCfg`) and one for the training parameters (`LeggedRobotCfgPPo`). 42 | 2. Both env and config classes use inheritance. 43 | 3. Each non-zero reward scale specified in `cfg` will add a function with a corresponding name to the list of elements which will be summed to get the total reward. 44 | 4. Tasks must be registered using `task_registry.register(name, EnvClass, EnvConfig, TrainConfig)`. This is done in `envs/__init__.py`, but can also be done from outside of this repository. 45 | 46 | ### Usage ### 47 | 1. Train: 48 | ```python legged_gym/scripts/train.py --task=anymal_c_flat``` 49 | - To run on CPU add following arguments: `--sim_device=cpu`, `--rl_device=cpu` (sim on CPU and rl on GPU is possible). 50 | - To run headless (no rendering) add `--headless`. 51 | - **Important**: To improve performance, once the training starts press `v` to stop the rendering. You can then enable it later to check the progress. 52 | - The trained policy is saved in `issacgym_anymal/logs//_/model_.pt`. Where `` and `` are defined in the train config. 53 | - The following command line arguments override the values set in the config files: 54 | - --task TASK: Task name. 55 | - --resume: Resume training from a checkpoint 56 | - --experiment_name EXPERIMENT_NAME: Name of the experiment to run or load. 57 | - --run_name RUN_NAME: Name of the run. 58 | - --load_run LOAD_RUN: Name of the run to load when resume=True. If -1: will load the last run. 59 | - --checkpoint CHECKPOINT: Saved model checkpoint number. If -1: will load the last checkpoint. 60 | - --num_envs NUM_ENVS: Number of environments to create. 61 | - --seed SEED: Random seed. 62 | - --max_iterations MAX_ITERATIONS: Maximum number of training iterations. 63 | 2. Play a trained policy: 64 | ```python legged_gym/scripts/play.py --task=anymal_c_flat``` 65 | - By default, the loaded policy is the last model of the last run of the experiment folder. 66 | - Other runs/model iteration can be selected by setting `load_run` and `checkpoint` in the train config. 67 | 68 | ### Adding a new environment ### 69 | The base environment `legged_robot` implements a rough terrain locomotion task. The corresponding cfg does not specify a robot asset (URDF/ MJCF) and has no reward scales. 70 | 71 | 1. Add a new folder to `envs/` with `'_config.py`, which inherit from an existing environment cfgs 72 | 2. If adding a new robot: 73 | - Add the corresponding assets to `resources/`. 74 | - In `cfg` set the asset path, define body names, default_joint_positions and PD gains. Specify the desired `train_cfg` and the name of the environment (python class). 75 | - In `train_cfg` set `experiment_name` and `run_name` 76 | 3. (If needed) implement your environment in .py, inherit from an existing environment, overwrite the desired functions and/or add your reward functions. 77 | 4. Register your env in `isaacgym_anymal/envs/__init__.py`. 78 | 5. Modify/Tune other parameters in your `cfg`, `cfg_train` as needed. To remove a reward set its scale to zero. Do not modify parameters of other envs! 79 | 80 | 81 | ### Troubleshooting ### 82 | 1. If you get the following error: `ImportError: libpython3.8m.so.1.0: cannot open shared object file: No such file or directory`, do: `sudo apt install libpython3.8`. It is also possible that you need to do `export LD_LIBRARY_PATH=/path/to/libpython/directory` / `export LD_LIBRARY_PATH=/path/to/conda/envs/your_env/lib`(for conda user. Replace /path/to/ to the corresponding path.). 83 | 84 | ### Known Issues ### 85 | 1. The contact forces reported by `net_contact_force_tensor` are unreliable when simulating on GPU with a triangle mesh terrain. A workaround is to use force sensors, but the force are propagated through the sensors of consecutive bodies resulting in an undesirable behaviour. However, for a legged robot it is possible to add sensors to the feet/end effector only and get the expected results. When using the force sensors make sure to exclude gravity from the reported forces with `sensor_options.enable_forward_dynamics_forces`. Example: 86 | ``` 87 | sensor_pose = gymapi.Transform() 88 | for name in feet_names: 89 | sensor_options = gymapi.ForceSensorProperties() 90 | sensor_options.enable_forward_dynamics_forces = False # for example gravity 91 | sensor_options.enable_constraint_solver_forces = True # for example contacts 92 | sensor_options.use_world_frame = True # report forces in world frame (easier to get vertical components) 93 | index = self.gym.find_asset_rigid_body_index(robot_asset, name) 94 | self.gym.create_asset_force_sensor(robot_asset, index, sensor_pose, sensor_options) 95 | (...) 96 | 97 | sensor_tensor = self.gym.acquire_force_sensor_tensor(self.sim) 98 | self.gym.refresh_force_sensor_tensor(self.sim) 99 | force_sensor_readings = gymtorch.wrap_tensor(sensor_tensor) 100 | self.sensor_forces = force_sensor_readings.view(self.num_envs, 4, 6)[..., :3] 101 | (...) 102 | 103 | self.gym.refresh_force_sensor_tensor(self.sim) 104 | contact = self.sensor_forces[:, :, 2] > 1. 105 | ``` 106 | -------------------------------------------------------------------------------- /legged_gym/env_cfg.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/env_cfg.pkl -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/go1_gym_deploy/__init__.py -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/autostart/start_controller.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | sudo docker stop foxy_controller || true 3 | sudo docker rm foxy_controller || true 4 | cd ~/go1_gym/go1_gym_deploy/docker/ 5 | sudo make autostart -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/autostart/start_unitree_sdk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | sudo docker stop foxy_controller || true 3 | sudo docker rm foxy_controller || true 4 | sudo kill $(ps aux |grep lcm_position | awk '{print $2}') 5 | cd ~/go1_gym/go1_gym_deploy/unitree_legged_sdk_bin/ 6 | yes "" | sudo ./lcm_position & -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:experimental 2 | 3 | FROM nvcr.io/nvidia/l4t-pytorch:r32.6.1-pth1.9-py3 4 | 5 | #ENV NVIDIA_VISIBLE_DEVICES ${NVIDIA_VISIBLE_DEVICES:-all} 6 | #ENV NVIDIA_DRIVER_CAPABILITIES ${NVIDIA_DRIVER_CAPABILITIES:+$NVIDIA_DRIVER_CAPABILITIES,}graphics 7 | 8 | # add new sudo user 9 | ENV USERNAME improbable 10 | ENV HOME /home/$USERNAME 11 | RUN useradd -m $USERNAME && \ 12 | echo "$USERNAME:$USERNAME" | chpasswd && \ 13 | usermod --shell /bin/bash $USERNAME && \ 14 | usermod -aG sudo $USERNAME && \ 15 | mkdir /etc/sudoers.d && \ 16 | echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/$USERNAME && \ 17 | chmod 0440 /etc/sudoers.d/$USERNAME && \ 18 | # Replace 1000 with your user/group id 19 | usermod --uid 1000 $USERNAME && \ 20 | groupmod --gid 1000 $USERNAME 21 | 22 | 23 | # install package 24 | ENV DEBIAN_FRONTEND=noninteractive 25 | RUN apt-get update && apt-get install -y --no-install-recommends \ 26 | build-essential \ 27 | curl \ 28 | sudo \ 29 | less \ 30 | emacs \ 31 | apt-utils \ 32 | tzdata \ 33 | git \ 34 | tmux \ 35 | bash-completion \ 36 | command-not-found \ 37 | libglib2.0-0 \ 38 | gstreamer1.0-plugins-* \ 39 | libgstreamer1.0-* \ 40 | libgstreamer-plugins-*1.0-* \ 41 | && \ 42 | apt-get clean && \ 43 | rm -rf /var/lib/apt/lists/* 44 | 45 | RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections 46 | 47 | #COPY config/nvidia_icd.json /usr/share/vulkan/icd.d/ 48 | 49 | 50 | USER root 51 | 52 | 53 | #RUN apt-get update && apt-get install -y python3-pip && pip3 install torch==1.9.0+cu111 torchvision==0.10.0+cu111 torchaudio==0.9.0 -f https://download.pytorch.org/whl/torch_stable.html 54 | 55 | 56 | # ================================================================== 57 | # Useful Libraries for Development 58 | # ------------------------------------------------------------------ 59 | #RUN apt update && apt install -y apt-transport-https ca-certificates curl software-properties-common 60 | #RUN curl -fsSL https://download.sublimetext.com/sublimehq-pub.gpg | apt-key add - && add-apt-repository "deb https://download.sublimetext.com/ apt/stable/" && apt update && apt install sublime-text 61 | 62 | 63 | # ================================================================== 64 | # Python dependencies defined in requirements.txt 65 | # ------------------------------------------------------------------ 66 | #RUN pip3 install --upgrade pip 67 | # copy local requirements file for pip install python deps 68 | #COPY ./requirements.txt /home/$USERNAME 69 | #WORKDIR /home/$USERNAME 70 | #RUN pip3 install -r requirements.txt 71 | 72 | # LCM 73 | RUN apt-get -y update && apt-get install -y make gcc-8 g++-8 74 | RUN cd /home/$USERNAME && git clone https://github.com/lcm-proj/lcm.git && cd lcm && mkdir build && cd build && cmake .. && make -j && make install 75 | RUN cd /home/$USERNAME/lcm/lcm-python && pip3 install -e . 76 | 77 | 78 | RUN apt-get install -y vim 79 | #RUN pip3 install pandas 80 | 81 | # ROS 82 | # ENV ROS_DISTRO melodic 83 | 84 | RUN apt-get install -y gnupg 85 | 86 | # COPY install_scripts/install_ros.sh /tmp/install_ros.sh 87 | # RUN chmod +x /tmp/install_ros.sh 88 | # RUN /tmp/install_ros.sh 89 | 90 | # # bootstrap rosdep 91 | # RUN rosdep init \ 92 | # && rosdep update 93 | 94 | # # create catkin workspace 95 | # ENV CATKIN_WS=/root/catkin_ws 96 | # RUN bash /opt/ros/melodic/setup.bash 97 | # RUN mkdir -p $CATKIN_WS/src 98 | # WORKDIR ${CATKIN_WS} 99 | # RUN catkin init 100 | # RUN catkin config --extend /opt/ros/$ROS_DISTRO \ 101 | # --cmake-args -DCMAKE_BUILD_TYPE=Release -DCATKIN_ENABLE_TESTING=False 102 | # WORKDIR $CATKIN_WS/src 103 | 104 | 105 | RUN apt-get update && apt-get install -y freeglut3-dev libudev-dev 106 | #COPY ./install_scripts/install_vision_opencv.sh /tmp/install_vision_opencv.sh 107 | #RUN chmod +x /tmp/install_vision_opencv.sh 108 | #RUN /tmp/install_vision_opencv.sh 109 | 110 | 111 | RUN apt-get install -y libgl1-mesa-dev libudev1 libudev-dev 112 | 113 | 114 | #RUN apt-get install unzip 115 | # 116 | #RUN cd ~ && \ 117 | # wget -O opencv.zip https://github.com/opencv/opencv/archive/4.5.1.zip && \ 118 | # wget -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/4.5.1.zip && \ 119 | # unzip opencv.zip && \ 120 | # unzip opencv_contrib.zip && \ 121 | # mv opencv-4.5.1 opencv && \ 122 | # mv opencv_contrib-4.5.1 opencv_contrib && \ 123 | # rm opencv.zip && \ 124 | # rm opencv_contrib.zip 125 | # 126 | #RUN cd ~/opencv && \ 127 | # mkdir build && \ 128 | # cd build && \ 129 | # cmake -D CMAKE_BUILD_TYPE=RELEASE \ 130 | # -D CMAKE_INSTALL_PREFIX=/usr \ 131 | # -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \ 132 | # -D EIGEN_INCLUDE_PATH=/usr/include/eigen3 \ 133 | # -D WITH_OPENCL=OFF \ 134 | # -D WITH_CUDA=OFF \ 135 | # -D CUDA_ARCH_BIN=5.3 \ 136 | # -D CUDA_ARCH_PTX="" \ 137 | # -D WITH_CUDNN=OFF \ 138 | # -D WITH_CUBLAS=OFF \ 139 | # -D ENABLE_FAST_MATH=ON \ 140 | # -D CUDA_FAST_MATH=OFF \ 141 | # -D OPENCV_DNN_CUDA=OFF \ 142 | # -D ENABLE_NEON=ON \ 143 | # -D WITH_QT=OFF \ 144 | # -D WITH_OPENMP=ON \ 145 | # -D WITH_OPENGL=ON \ 146 | # -D BUILD_TIFF=ON \ 147 | # -D WITH_FFMPEG=ON \ 148 | # -D WITH_GSTREAMER=ON \ 149 | # -D WITH_TBB=ON \ 150 | # -D BUILD_TBB=ON \ 151 | # -D BUILD_TESTS=OFF \ 152 | # -D WITH_EIGEN=ON \ 153 | # -D WITH_V4L=ON \ 154 | # -D WITH_LIBV4L=ON \ 155 | # -D OPENCV_ENABLE_NONFREE=ON \ 156 | # -D INSTALL_C_EXAMPLES=OFF \ 157 | # -D INSTALL_PYTHON_EXAMPLES=OFF \ 158 | # -D BUILD_NEW_PYTHON_SUPPORT=ON \ 159 | # -D BUILD_opencv_python3=TRUE \ 160 | # -D OPENCV_GENERATE_PKGCONFIG=ON \ 161 | # -D BUILD_EXAMPLES=OFF .. && \ 162 | # make -j4 && cd ~ && \ 163 | # # sudo rm -r /usr/include/opencv4/opencv2 && \ 164 | # cd ~/opencv/build && \ 165 | # sudo make install && \ 166 | # sudo ldconfig && \ 167 | # make clean && \ 168 | # sudo apt-get update 169 | 170 | RUN apt-get install -y libgtk2.0-dev pkg-config 171 | RUN pip3 install opencv-python opencv-contrib-python 172 | 173 | #################################################################################### 174 | ###### START HERE -- Install whatever dependencies you need specific to this project! 175 | #################################################################################### 176 | 177 | 178 | #COPY ./rsc/IsaacGym_Preview_2_Package.tar.gz /home/$USERNAME/ 179 | #RUN cd /home/$USERNAME && tar -xvzf IsaacGym_Preview_2_Package.tar.gz 180 | #COPY ./rsc/learning_to_walk_in_minutes.zip /home/$USERNAME/ 181 | #RUN apt-get install unzip && cd /home/$USERNAME/ && unzip learning_to_walk_in_minutes.zip && cd ./code/rl-pytorch && pip3 install -e . 182 | #RUN cd /home/$USERNAME/isaacgym/python && pip3 install -e . 183 | #RUN cd /home/$USERNAME/code/isaacgym_anymal && pip3 install -e . 184 | #COPY ./src/isaacgym_anymal/ /home/$USERNAME/code/isaacgym_anymal/ 185 | 186 | # setup entrypoint 187 | COPY entrypoint.sh / 188 | 189 | ENTRYPOINT ["/entrypoint.sh"] 190 | CMD ["bash"] 191 | -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/docker/Makefile: -------------------------------------------------------------------------------- 1 | default: build 2 | build: 3 | docker build -t jetson-model-deployment . 4 | clean-build: 5 | docker build -t jetson-model-deployment . --no-cache=true 6 | run: 7 | docker stop foxy_controller || true 8 | docker rm foxy_controller || true 9 | docker run -it \ 10 | --env="DISPLAY" \ 11 | --env="QT_X11_NO_MITSHM=1" \ 12 | --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \ 13 | --env="XAUTHORITY=${XAUTH}" \ 14 | --volume="${XAUTH}:${XAUTH}" \ 15 | --volume="/home/unitree/go1_gym:/home/isaac/go1_gym" \ 16 | --privileged \ 17 | --runtime=nvidia \ 18 | --net=host \ 19 | --workdir="/home/isaac/go1_gym" \ 20 | --name="foxy_controller" \ 21 | jetson-model-deployment bash 22 | autostart: 23 | docker stop foxy_controller || true 24 | docker rm foxy_controller || true 25 | docker run -d\ 26 | --env="DISPLAY" \ 27 | --env="QT_X11_NO_MITSHM=1" \ 28 | --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \ 29 | --env="XAUTHORITY=${XAUTH}" \ 30 | --volume="${XAUTH}:${XAUTH}" \ 31 | --volume="/home/unitree/go1_gym:/home/isaac/go1_gym" \ 32 | --privileged \ 33 | --runtime=nvidia \ 34 | --net=host \ 35 | --workdir="/home/isaac/go1_gym" \ 36 | --name="foxy_controller" \ 37 | jetson-model-deployment tail -f /dev/null 38 | docker start foxy_controller 39 | docker exec foxy_controller bash -c 'cd /home/isaac/go1_gym/ && python3 setup.py install && cd go1_gym_deploy/scripts && ls && python3 deploy_policy.py' 40 | -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/docker/unzip_image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker load -i deployment_image.tar 3 | -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/docker/zip_image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker save -o deployment_image.tar jetson-model-deployment:latest 3 | -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/envs/Saved_Models.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/go1_gym_deploy/envs/Saved_Models.zip -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/envs/Saved_Models/actor_dwaq.pt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/go1_gym_deploy/envs/Saved_Models/actor_dwaq.pt -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/envs/Saved_Models/encoder_dwaq.pt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/go1_gym_deploy/envs/Saved_Models/encoder_dwaq.pt -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/envs/Saved_Models/encoder_mu_dwaq.pt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/go1_gym_deploy/envs/Saved_Models/encoder_mu_dwaq.pt -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/envs/Saved_Models/encoder_var_dwaq.pt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/go1_gym_deploy/envs/Saved_Models/encoder_var_dwaq.pt -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/envs/Saved_Models/parameters.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/go1_gym_deploy/envs/Saved_Models/parameters.pkl -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/envs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/go1_gym_deploy/envs/__init__.py -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/envs/history_wrapper.py: -------------------------------------------------------------------------------- 1 | # import isaacgym 2 | 3 | # assert isaacgym, "import isaacgym before pytorch" 4 | import torch 5 | 6 | 7 | class HistoryWrapper: 8 | def __init__(self, env): 9 | self.env = env 10 | 11 | if isinstance(self.env.cfg, dict): 12 | self.obs_history_length = self.env.cfg["env"]["num_observation_history"] 13 | else: 14 | self.obs_history_length = self.env.cfg.env.num_observation_history 15 | self.num_obs_history = self.obs_history_length * self.env.num_obs 16 | self.obs_history = torch.zeros(self.env.num_envs, self.num_obs_history, dtype=torch.float, 17 | device=self.env.device, requires_grad=False) 18 | self.num_privileged_obs = self.env.num_privileged_obs 19 | 20 | def step(self, action): 21 | obs, rew, done, info = self.env.step(action) 22 | privileged_obs = info["privileged_obs"] 23 | 24 | self.obs_history = torch.cat((self.obs_history[:, self.env.num_obs:], obs), dim=-1) 25 | return {'obs': obs, 'privileged_obs': privileged_obs, 'obs_history': self.obs_history}, rew, done, info 26 | 27 | def get_observations(self): 28 | obs = self.env.get_observations() 29 | privileged_obs = self.env.get_privileged_observations() 30 | self.obs_history = torch.cat((self.obs_history[:, self.env.num_obs:], obs), dim=-1) 31 | return {'obs': obs, 'privileged_obs': privileged_obs, 'obs_history': self.obs_history} 32 | 33 | def get_obs(self): 34 | obs = self.env.get_obs() 35 | privileged_obs = self.env.get_privileged_observations() 36 | self.obs_history = torch.cat((self.obs_history[:, self.env.num_obs:], obs), dim=-1) 37 | return {'obs': obs, 'privileged_obs': privileged_obs, 'obs_history': self.obs_history} 38 | 39 | def reset_idx(self, env_ids): # it might be a problem that this isn't getting called!! 40 | ret = self.env.reset_idx(env_ids) 41 | self.obs_history[env_ids, :] = 0 42 | return ret 43 | 44 | def reset(self): 45 | ret = self.env.reset() 46 | privileged_obs = self.env.get_privileged_observations() 47 | self.obs_history[:, :] = 0 48 | return {"obs": ret, "privileged_obs": privileged_obs, "obs_history": self.obs_history} 49 | 50 | def __getattr__(self, name): 51 | return getattr(self.env, name) 52 | -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/installer/install_deployment_code.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "======================================" 4 | echo "== Go1 Sim-to-Real Installation Kit ==" 5 | echo "======================================" 6 | echo "" 7 | echo "Author: Gabriel Margolis, Improbable AI Lab, MIT" 8 | echo "This software is intended to support controls research. It includes safety features but may still damage your Go1. The user assumes all risk." 9 | echo "" 10 | 11 | read -r -p "Extract docker container? [y/N] " response 12 | if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]] 13 | then 14 | # load docker image 15 | echo "[Step 1] Extracting docker image..." 16 | docker load -i ../scripts/deployment_image.tar 17 | printf "\nDone!\n" 18 | else 19 | echo "Quitting" 20 | fi 21 | 22 | 23 | -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/lcm_types/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/go1_gym_deploy/lcm_types/__init__.py -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/lcm_types/camera_message_lcmt.py: -------------------------------------------------------------------------------- 1 | """LCM type definitions 2 | This file automatically generated by lcm. 3 | DO NOT MODIFY BY HAND!!!! 4 | """ 5 | 6 | try: 7 | import cStringIO.StringIO as BytesIO 8 | except ImportError: 9 | from io import BytesIO 10 | import struct 11 | 12 | class camera_message_lcmt(object): 13 | __slots__ = ["data"] 14 | 15 | __typenames__ = ["byte"] 16 | 17 | __dimensions__ = [[278400]] 18 | 19 | def __init__(self): 20 | self.data = "" 21 | 22 | def encode(self): 23 | buf = BytesIO() 24 | buf.write(camera_message_lcmt._get_packed_fingerprint()) 25 | self._encode_one(buf) 26 | return buf.getvalue() 27 | 28 | def _encode_one(self, buf): 29 | buf.write(bytearray(self.data[:278400])) 30 | 31 | def decode(data): 32 | if hasattr(data, 'read'): 33 | buf = data 34 | else: 35 | buf = BytesIO(data) 36 | if buf.read(8) != camera_message_lcmt._get_packed_fingerprint(): 37 | raise ValueError("Decode error") 38 | return camera_message_lcmt._decode_one(buf) 39 | decode = staticmethod(decode) 40 | 41 | def _decode_one(buf): 42 | self = camera_message_lcmt() 43 | self.data = buf.read(278400) 44 | return self 45 | _decode_one = staticmethod(_decode_one) 46 | 47 | _hash = None 48 | def _get_hash_recursive(parents): 49 | if camera_message_lcmt in parents: return 0 50 | tmphash = (0x1610a8a9f4d174b7) & 0xffffffffffffffff 51 | tmphash = (((tmphash<<1)&0xffffffffffffffff) + (tmphash>>63)) & 0xffffffffffffffff 52 | return tmphash 53 | _get_hash_recursive = staticmethod(_get_hash_recursive) 54 | _packed_fingerprint = None 55 | 56 | def _get_packed_fingerprint(): 57 | if camera_message_lcmt._packed_fingerprint is None: 58 | camera_message_lcmt._packed_fingerprint = struct.pack(">Q", camera_message_lcmt._get_hash_recursive([])) 59 | return camera_message_lcmt._packed_fingerprint 60 | _get_packed_fingerprint = staticmethod(_get_packed_fingerprint) -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/lcm_types/camera_message_rect_wide.py: -------------------------------------------------------------------------------- 1 | """LCM type definitions 2 | This file automatically generated by lcm. 3 | DO NOT MODIFY BY HAND!!!! 4 | """ 5 | 6 | try: 7 | import cStringIO.StringIO as BytesIO 8 | except ImportError: 9 | from io import BytesIO 10 | import struct 11 | 12 | class camera_message_rect_wide(object): 13 | __slots__ = ["data"] 14 | 15 | def __init__(self): 16 | self.data = "" 17 | 18 | def encode(self): 19 | buf = BytesIO() 20 | buf.write(camera_message_rect_wide._get_packed_fingerprint()) 21 | self._encode_one(buf) 22 | return buf.getvalue() 23 | 24 | def _encode_one(self, buf): 25 | buf.write(bytearray(self.data[:34800])) 26 | 27 | def decode(data): 28 | if hasattr(data, 'read'): 29 | buf = data 30 | else: 31 | buf = BytesIO(data) 32 | if buf.read(8) != camera_message_rect_wide._get_packed_fingerprint(): 33 | raise ValueError("Decode error") 34 | return camera_message_rect_wide._decode_one(buf) 35 | decode = staticmethod(decode) 36 | 37 | def _decode_one(buf): 38 | self = camera_message_rect_wide() 39 | self.data = buf.read(34800) 40 | return self 41 | _decode_one = staticmethod(_decode_one) 42 | 43 | _hash = None 44 | def _get_hash_recursive(parents): 45 | if camera_message_rect_wide in parents: return 0 46 | tmphash = (0xc3e9f058530b2a8b) & 0xffffffffffffffff 47 | tmphash = (((tmphash<<1)&0xffffffffffffffff) + (tmphash>>63)) & 0xffffffffffffffff 48 | return tmphash 49 | _get_hash_recursive = staticmethod(_get_hash_recursive) 50 | _packed_fingerprint = None 51 | 52 | def _get_packed_fingerprint(): 53 | if camera_message_rect_wide._packed_fingerprint is None: 54 | camera_message_rect_wide._packed_fingerprint = struct.pack(">Q", camera_message_rect_wide._get_hash_recursive([])) 55 | return camera_message_rect_wide._packed_fingerprint 56 | _get_packed_fingerprint = staticmethod(_get_packed_fingerprint) 57 | 58 | -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/lcm_types/leg_control_data_lcmt.lcm: -------------------------------------------------------------------------------- 1 | struct leg_control_data_lcmt 2 | { 3 | float q[12]; 4 | float qd[12]; 5 | float p[12]; 6 | float v[12]; 7 | float tau_est[12]; 8 | int64_t timestamp_us; 9 | int64_t id; 10 | int64_t robot_id; 11 | } -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/lcm_types/leg_control_data_lcmt.py: -------------------------------------------------------------------------------- 1 | """LCM type definitions 2 | This file automatically generated by lcm. 3 | DO NOT MODIFY BY HAND!!!! 4 | """ 5 | 6 | try: 7 | import cStringIO.StringIO as BytesIO 8 | except ImportError: 9 | from io import BytesIO 10 | import struct 11 | 12 | 13 | class leg_control_data_lcmt(object): 14 | __slots__ = ["q", "qd", "p", "v", "tau_est", "timestamp_us", "id", "robot_id"] 15 | 16 | __typenames__ = ["float", "float", "float", "float", "float", "int64_t", "int64_t", "int64_t"] 17 | 18 | __dimensions__ = [[12], [12], [12], [12], [12], None, None, None] 19 | 20 | def __init__(self): 21 | self.q = [0.0 for dim0 in range(12)] 22 | self.qd = [0.0 for dim0 in range(12)] 23 | self.p = [0.0 for dim0 in range(12)] 24 | self.v = [0.0 for dim0 in range(12)] 25 | self.tau_est = [0.0 for dim0 in range(12)] 26 | self.timestamp_us = 0 27 | self.id = 0 28 | self.robot_id = 0 29 | 30 | def encode(self): 31 | buf = BytesIO() 32 | buf.write(leg_control_data_lcmt._get_packed_fingerprint()) 33 | self._encode_one(buf) 34 | return buf.getvalue() 35 | 36 | def _encode_one(self, buf): 37 | buf.write(struct.pack('>12f', *self.q[:12])) 38 | buf.write(struct.pack('>12f', *self.qd[:12])) 39 | buf.write(struct.pack('>12f', *self.p[:12])) 40 | buf.write(struct.pack('>12f', *self.v[:12])) 41 | buf.write(struct.pack('>12f', *self.tau_est[:12])) 42 | buf.write(struct.pack(">qqq", self.timestamp_us, self.id, self.robot_id)) 43 | 44 | def decode(data): 45 | if hasattr(data, 'read'): 46 | buf = data 47 | else: 48 | buf = BytesIO(data) 49 | if buf.read(8) != leg_control_data_lcmt._get_packed_fingerprint(): 50 | raise ValueError("Decode error") 51 | return leg_control_data_lcmt._decode_one(buf) 52 | 53 | decode = staticmethod(decode) 54 | 55 | def _decode_one(buf): 56 | self = leg_control_data_lcmt() 57 | self.q = struct.unpack('>12f', buf.read(48)) 58 | self.qd = struct.unpack('>12f', buf.read(48)) 59 | self.p = struct.unpack('>12f', buf.read(48)) 60 | self.v = struct.unpack('>12f', buf.read(48)) 61 | self.tau_est = struct.unpack('>12f', buf.read(48)) 62 | self.timestamp_us, self.id, self.robot_id = struct.unpack(">qqq", buf.read(24)) 63 | return self 64 | 65 | _decode_one = staticmethod(_decode_one) 66 | 67 | def _get_hash_recursive(parents): 68 | if leg_control_data_lcmt in parents: return 0 69 | tmphash = (0xa9a928b534bfc487) & 0xffffffffffffffff 70 | tmphash = (((tmphash << 1) & 0xffffffffffffffff) + (tmphash >> 63)) & 0xffffffffffffffff 71 | return tmphash 72 | 73 | _get_hash_recursive = staticmethod(_get_hash_recursive) 74 | _packed_fingerprint = None 75 | 76 | def _get_packed_fingerprint(): 77 | if leg_control_data_lcmt._packed_fingerprint is None: 78 | leg_control_data_lcmt._packed_fingerprint = struct.pack(">Q", leg_control_data_lcmt._get_hash_recursive([])) 79 | return leg_control_data_lcmt._packed_fingerprint 80 | 81 | _get_packed_fingerprint = staticmethod(_get_packed_fingerprint) 82 | 83 | def get_hash(self): 84 | """Get the LCM hash of the struct""" 85 | return struct.unpack(">Q", leg_control_data_lcmt._get_packed_fingerprint())[0] 86 | -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/lcm_types/pd_tau_targets_lcmt.lcm: -------------------------------------------------------------------------------- 1 | struct pd_tau_targets_lcmt 2 | { 3 | double q_des[12]; 4 | double qd_des[12]; 5 | double tau_ff[12]; 6 | double kp[12]; 7 | double kd[12]; 8 | int64_t timestamp_us; 9 | int64_t id; 10 | int64_t robot_id; 11 | double se_contactState[4]; 12 | } -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/lcm_types/pd_tau_targets_lcmt.py: -------------------------------------------------------------------------------- 1 | """LCM type definitions 2 | This file automatically generated by lcm. 3 | DO NOT MODIFY BY HAND!!!! 4 | """ 5 | 6 | try: 7 | import cStringIO.StringIO as BytesIO 8 | except ImportError: 9 | from io import BytesIO 10 | import struct 11 | 12 | 13 | class pd_tau_targets_lcmt(object): 14 | __slots__ = ["q_des", "qd_des", "tau_ff", "kp", "kd", "timestamp_us", "id", "robot_id", "se_contactState"] 15 | 16 | __typenames__ = ["double", "double", "double", "double", "double", "int64_t", "int64_t", "int64_t", "double"] 17 | 18 | __dimensions__ = [[12], [12], [12], [12], [12], None, None, None, [4]] 19 | 20 | def __init__(self): 21 | self.q_des = [0.0 for dim0 in range(12)] 22 | self.qd_des = [0.0 for dim0 in range(12)] 23 | self.tau_ff = [0.0 for dim0 in range(12)] 24 | self.kp = [0.0 for dim0 in range(12)] 25 | self.kd = [0.0 for dim0 in range(12)] 26 | self.timestamp_us = 0 27 | self.id = 0 28 | self.robot_id = 0 29 | self.se_contactState = [0.0 for dim0 in range(4)] 30 | 31 | def encode(self): 32 | buf = BytesIO() 33 | buf.write(pd_tau_targets_lcmt._get_packed_fingerprint()) 34 | self._encode_one(buf) 35 | return buf.getvalue() 36 | 37 | def _encode_one(self, buf): 38 | buf.write(struct.pack('>12d', *self.q_des[:12])) 39 | buf.write(struct.pack('>12d', *self.qd_des[:12])) 40 | buf.write(struct.pack('>12d', *self.tau_ff[:12])) 41 | buf.write(struct.pack('>12d', *self.kp[:12])) 42 | buf.write(struct.pack('>12d', *self.kd[:12])) 43 | buf.write(struct.pack(">qqq", self.timestamp_us, self.id, self.robot_id)) 44 | buf.write(struct.pack('>4d', *self.se_contactState[:4])) 45 | 46 | def decode(data): 47 | if hasattr(data, 'read'): 48 | buf = data 49 | else: 50 | buf = BytesIO(data) 51 | if buf.read(8) != pd_tau_targets_lcmt._get_packed_fingerprint(): 52 | raise ValueError("Decode error") 53 | return pd_tau_targets_lcmt._decode_one(buf) 54 | 55 | decode = staticmethod(decode) 56 | 57 | def _decode_one(buf): 58 | self = pd_tau_targets_lcmt() 59 | self.q_des = struct.unpack('>12d', buf.read(96)) 60 | self.qd_des = struct.unpack('>12d', buf.read(96)) 61 | self.tau_ff = struct.unpack('>12d', buf.read(96)) 62 | self.kp = struct.unpack('>12d', buf.read(96)) 63 | self.kd = struct.unpack('>12d', buf.read(96)) 64 | self.timestamp_us, self.id, self.robot_id = struct.unpack(">qqq", buf.read(24)) 65 | self.se_contactState = struct.unpack('>4d', buf.read(32)) 66 | return self 67 | 68 | _decode_one = staticmethod(_decode_one) 69 | 70 | def _get_hash_recursive(parents): 71 | if pd_tau_targets_lcmt in parents: return 0 72 | tmphash = (0x6d88128ef1291cc1) & 0xffffffffffffffff 73 | tmphash = (((tmphash << 1) & 0xffffffffffffffff) + (tmphash >> 63)) & 0xffffffffffffffff 74 | return tmphash 75 | 76 | _get_hash_recursive = staticmethod(_get_hash_recursive) 77 | _packed_fingerprint = None 78 | 79 | def _get_packed_fingerprint(): 80 | if pd_tau_targets_lcmt._packed_fingerprint is None: 81 | pd_tau_targets_lcmt._packed_fingerprint = struct.pack(">Q", pd_tau_targets_lcmt._get_hash_recursive([])) 82 | return pd_tau_targets_lcmt._packed_fingerprint 83 | 84 | _get_packed_fingerprint = staticmethod(_get_packed_fingerprint) 85 | 86 | def get_hash(self): 87 | """Get the LCM hash of the struct""" 88 | return struct.unpack(">Q", pd_tau_targets_lcmt._get_packed_fingerprint())[0] 89 | -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/lcm_types/rc_command_lcmt.lcm: -------------------------------------------------------------------------------- 1 | struct rc_command_lcmt 2 | { 3 | int16_t mode; 4 | float left_stick[2]; 5 | float right_stick[2]; 6 | float knobs[2]; 7 | int16_t left_upper_switch; 8 | int16_t left_lower_left_switch; 9 | int16_t left_lower_right_switch; 10 | int16_t right_upper_switch; 11 | int16_t right_lower_left_switch; 12 | int16_t right_lower_right_switch; 13 | } -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/lcm_types/rc_command_lcmt.py: -------------------------------------------------------------------------------- 1 | """LCM type definitions 2 | This file automatically generated by lcm. 3 | DO NOT MODIFY BY HAND!!!! 4 | """ 5 | 6 | try: 7 | import cStringIO.StringIO as BytesIO 8 | except ImportError: 9 | from io import BytesIO 10 | import struct 11 | 12 | 13 | class rc_command_lcmt(object): 14 | __slots__ = ["mode", "left_stick", "right_stick", "knobs", "left_upper_switch", "left_lower_left_switch", 15 | "left_lower_right_switch", "right_upper_switch", "right_lower_left_switch", "right_lower_right_switch"] 16 | 17 | __typenames__ = ["int16_t", "float", "float", "float", "int16_t", "int16_t", "int16_t", "int16_t", "int16_t", 18 | "int16_t"] 19 | 20 | __dimensions__ = [None, [2], [2], [2], None, None, None, None, None, None] 21 | 22 | def __init__(self): 23 | self.mode = 0 24 | self.left_stick = [0.0 for dim0 in range(2)] 25 | self.right_stick = [0.0 for dim0 in range(2)] 26 | self.knobs = [0.0 for dim0 in range(2)] 27 | self.left_upper_switch = 0 28 | self.left_lower_left_switch = 0 29 | self.left_lower_right_switch = 0 30 | self.right_upper_switch = 0 31 | self.right_lower_left_switch = 0 32 | self.right_lower_right_switch = 0 33 | 34 | def encode(self): 35 | buf = BytesIO() 36 | buf.write(rc_command_lcmt._get_packed_fingerprint()) 37 | self._encode_one(buf) 38 | return buf.getvalue() 39 | 40 | def _encode_one(self, buf): 41 | buf.write(struct.pack(">h", self.mode)) 42 | buf.write(struct.pack('>2f', *self.left_stick[:2])) 43 | buf.write(struct.pack('>2f', *self.right_stick[:2])) 44 | buf.write(struct.pack('>2f', *self.knobs[:2])) 45 | buf.write( 46 | struct.pack(">hhhhhh", self.left_upper_switch, self.left_lower_left_switch, self.left_lower_right_switch, 47 | self.right_upper_switch, self.right_lower_left_switch, self.right_lower_right_switch)) 48 | 49 | def decode(data): 50 | if hasattr(data, 'read'): 51 | buf = data 52 | else: 53 | buf = BytesIO(data) 54 | if buf.read(8) != rc_command_lcmt._get_packed_fingerprint(): 55 | raise ValueError("Decode error") 56 | return rc_command_lcmt._decode_one(buf) 57 | 58 | decode = staticmethod(decode) 59 | 60 | def _decode_one(buf): 61 | self = rc_command_lcmt() 62 | self.mode = struct.unpack(">h", buf.read(2))[0] 63 | self.left_stick = struct.unpack('>2f', buf.read(8)) 64 | self.right_stick = struct.unpack('>2f', buf.read(8)) 65 | self.knobs = struct.unpack('>2f', buf.read(8)) 66 | self.left_upper_switch, self.left_lower_left_switch, self.left_lower_right_switch, self.right_upper_switch, self.right_lower_left_switch, self.right_lower_right_switch = struct.unpack( 67 | ">hhhhhh", buf.read(12)) 68 | return self 69 | 70 | _decode_one = staticmethod(_decode_one) 71 | 72 | def _get_hash_recursive(parents): 73 | if rc_command_lcmt in parents: return 0 74 | tmphash = (0xc7726b02ec3e7de2) & 0xffffffffffffffff 75 | tmphash = (((tmphash << 1) & 0xffffffffffffffff) + (tmphash >> 63)) & 0xffffffffffffffff 76 | return tmphash 77 | 78 | _get_hash_recursive = staticmethod(_get_hash_recursive) 79 | _packed_fingerprint = None 80 | 81 | def _get_packed_fingerprint(): 82 | if rc_command_lcmt._packed_fingerprint is None: 83 | rc_command_lcmt._packed_fingerprint = struct.pack(">Q", rc_command_lcmt._get_hash_recursive([])) 84 | return rc_command_lcmt._packed_fingerprint 85 | 86 | _get_packed_fingerprint = staticmethod(_get_packed_fingerprint) 87 | 88 | def get_hash(self): 89 | """Get the LCM hash of the struct""" 90 | return struct.unpack(">Q", rc_command_lcmt._get_packed_fingerprint())[0] 91 | -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/lcm_types/state_estimator_lcmt.lcm: -------------------------------------------------------------------------------- 1 | struct state_estimator_lcmt 2 | { 3 | float p[3]; 4 | float vWorld[3]; 5 | float vBody[3]; 6 | float rpy[3]; 7 | float omegaBody[3]; 8 | float omegaWorld[3]; 9 | float quat[4]; 10 | float contact_estimate[4]; 11 | float aBody[3]; 12 | float aWorld[3]; 13 | int64_t timestamp_us; 14 | int64_t id; 15 | int64_t robot_id; 16 | } 17 | -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/lcm_types/state_estimator_lcmt.py: -------------------------------------------------------------------------------- 1 | """LCM type definitions 2 | This file automatically generated by lcm. 3 | DO NOT MODIFY BY HAND!!!! 4 | """ 5 | 6 | try: 7 | import cStringIO.StringIO as BytesIO 8 | except ImportError: 9 | from io import BytesIO 10 | import struct 11 | 12 | 13 | class state_estimator_lcmt(object): 14 | __slots__ = ["p", "vWorld", "vBody", "rpy", "omegaBody", "omegaWorld", "quat", "contact_estimate", "aBody", 15 | "aWorld", "timestamp_us", "id", "robot_id"] 16 | 17 | __typenames__ = ["float", "float", "float", "float", "float", "float", "float", "float", "float", "float", 18 | "int64_t", "int64_t", "int64_t"] 19 | 20 | __dimensions__ = [[3], [3], [3], [3], [3], [3], [4], [4], [3], [3], None, None, None] 21 | 22 | def __init__(self): 23 | self.p = [0.0 for dim0 in range(3)] 24 | self.vWorld = [0.0 for dim0 in range(3)] 25 | self.vBody = [0.0 for dim0 in range(3)] 26 | self.rpy = [0.0 for dim0 in range(3)] 27 | self.omegaBody = [0.0 for dim0 in range(3)] 28 | self.omegaWorld = [0.0 for dim0 in range(3)] 29 | self.quat = [0.0 for dim0 in range(4)] 30 | self.contact_estimate = [0.0 for dim0 in range(4)] 31 | self.aBody = [0.0 for dim0 in range(3)] 32 | self.aWorld = [0.0 for dim0 in range(3)] 33 | self.timestamp_us = 0 34 | self.id = 0 35 | self.robot_id = 0 36 | 37 | def encode(self): 38 | buf = BytesIO() 39 | buf.write(state_estimator_lcmt._get_packed_fingerprint()) 40 | self._encode_one(buf) 41 | return buf.getvalue() 42 | 43 | def _encode_one(self, buf): 44 | buf.write(struct.pack('>3f', *self.p[:3])) 45 | buf.write(struct.pack('>3f', *self.vWorld[:3])) 46 | buf.write(struct.pack('>3f', *self.vBody[:3])) 47 | buf.write(struct.pack('>3f', *self.rpy[:3])) 48 | buf.write(struct.pack('>3f', *self.omegaBody[:3])) 49 | buf.write(struct.pack('>3f', *self.omegaWorld[:3])) 50 | buf.write(struct.pack('>4f', *self.quat[:4])) 51 | buf.write(struct.pack('>4f', *self.contact_estimate[:4])) 52 | buf.write(struct.pack('>3f', *self.aBody[:3])) 53 | buf.write(struct.pack('>3f', *self.aWorld[:3])) 54 | buf.write(struct.pack(">qqq", self.timestamp_us, self.id, self.robot_id)) 55 | 56 | def decode(data): 57 | if hasattr(data, 'read'): 58 | buf = data 59 | else: 60 | buf = BytesIO(data) 61 | if buf.read(8) != state_estimator_lcmt._get_packed_fingerprint(): 62 | raise ValueError("Decode error") 63 | return state_estimator_lcmt._decode_one(buf) 64 | 65 | decode = staticmethod(decode) 66 | 67 | def _decode_one(buf): 68 | self = state_estimator_lcmt() 69 | self.p = struct.unpack('>3f', buf.read(12)) 70 | self.vWorld = struct.unpack('>3f', buf.read(12)) 71 | self.vBody = struct.unpack('>3f', buf.read(12)) 72 | self.rpy = struct.unpack('>3f', buf.read(12)) 73 | self.omegaBody = struct.unpack('>3f', buf.read(12)) 74 | self.omegaWorld = struct.unpack('>3f', buf.read(12)) 75 | self.quat = struct.unpack('>4f', buf.read(16)) 76 | self.contact_estimate = struct.unpack('>4f', buf.read(16)) 77 | self.aBody = struct.unpack('>3f', buf.read(12)) 78 | self.aWorld = struct.unpack('>3f', buf.read(12)) 79 | self.timestamp_us, self.id, self.robot_id = struct.unpack(">qqq", buf.read(24)) 80 | return self 81 | 82 | _decode_one = staticmethod(_decode_one) 83 | 84 | def _get_hash_recursive(parents): 85 | if state_estimator_lcmt in parents: return 0 86 | tmphash = (0xea87c8282effe5b6) & 0xffffffffffffffff 87 | tmphash = (((tmphash << 1) & 0xffffffffffffffff) + (tmphash >> 63)) & 0xffffffffffffffff 88 | return tmphash 89 | 90 | _get_hash_recursive = staticmethod(_get_hash_recursive) 91 | _packed_fingerprint = None 92 | 93 | def _get_packed_fingerprint(): 94 | if state_estimator_lcmt._packed_fingerprint is None: 95 | state_estimator_lcmt._packed_fingerprint = struct.pack(">Q", state_estimator_lcmt._get_hash_recursive([])) 96 | return state_estimator_lcmt._packed_fingerprint 97 | 98 | _get_packed_fingerprint = staticmethod(_get_packed_fingerprint) 99 | 100 | def get_hash(self): 101 | """Get the LCM hash of the struct""" 102 | return struct.unpack(">Q", state_estimator_lcmt._get_packed_fingerprint())[0] 103 | -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/scripts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/go1_gym_deploy/scripts/__init__.py -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/scripts/deploy_policy.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import pickle as pkl 3 | import lcm 4 | import sys 5 | 6 | from go1_gym_deploy.utils.deployment_runner import DeploymentRunner 7 | from go1_gym_deploy.envs.lcm_agent import LCMAgent 8 | from go1_gym_deploy.utils.cheetah_state_estimator import StateEstimator 9 | from go1_gym_deploy.utils.command_profile import * 10 | 11 | import pathlib 12 | 13 | lc = lcm.LCM("udpm://239.255.76.67:7667?ttl=255") 14 | 15 | def load_and_run_policy(label, experiment_name, max_vel=1.0, max_yaw_vel=1.0): 16 | # load agent 17 | dirs = glob.glob(f"../../runs/{label}/*") 18 | logdir = sorted(dirs)[0] 19 | 20 | with open(logdir+"/parameters.pkl", 'rb') as file: 21 | pkl_cfg = pkl.load(file) 22 | print(pkl_cfg.keys()) 23 | cfg = pkl_cfg["Cfg"] 24 | print(cfg.keys()) 25 | 26 | 27 | se = StateEstimator(lc) 28 | 29 | control_dt = 0.02 30 | command_profile = RCControllerProfile(dt=control_dt, state_estimator=se, x_scale=max_vel, y_scale=0.6, yaw_scale=max_yaw_vel) 31 | 32 | hardware_agent = LCMAgent(cfg, se, command_profile) 33 | se.spin() 34 | 35 | from go1_gym_deploy.envs.history_wrapper import HistoryWrapper 36 | hardware_agent = HistoryWrapper(hardware_agent) 37 | 38 | policy = load_policy(logdir) 39 | 40 | # load runner 41 | root = f"{pathlib.Path(__file__).parent.resolve()}/../../logs/" 42 | pathlib.Path(root).mkdir(parents=True, exist_ok=True) 43 | deployment_runner = DeploymentRunner(experiment_name=experiment_name, se=None, 44 | log_root=f"{root}/{experiment_name}") 45 | deployment_runner.add_control_agent(hardware_agent, "hardware_closed_loop") 46 | deployment_runner.add_policy(policy) 47 | deployment_runner.add_command_profile(command_profile) 48 | 49 | if len(sys.argv) >= 2: 50 | max_steps = int(sys.argv[1]) 51 | else: 52 | max_steps = 10000000 53 | print(f'max steps {max_steps}') 54 | 55 | deployment_runner.run(max_steps=max_steps, logging=True) 56 | 57 | def load_policy(logdir): 58 | actor=torch.jit.load(logdir + '/actor_1.pt') 59 | encoder=torch.jit.load(logdir + "/encoder_1.pt") 60 | fc_mu = torch.jit.load(logdir + '/encoder_mu_1.pt') 61 | fc_var = torch.jit.load(logdir + '/encoder_var_1.pt') 62 | 63 | 64 | def policy(obs, info): 65 | i = 0 66 | 67 | h = encoder(obs["obs_history"].to('cpu').float()) 68 | mu = fc_mu(h) 69 | log_var = fc_var(h) 70 | std = torch.exp(0.5 * log_var) 71 | eps = torch.randn_like(std) 72 | latent = mu + eps * std 73 | action = actor(torch.cat((obs["obs"].to('cpu'), latent), dim=-1)) 74 | info['latent'] = latent 75 | return action 76 | 77 | return policy 78 | 79 | 80 | if __name__ == '__main__': 81 | label = "gait-conditioned-agility/pretrain-v0/train" 82 | 83 | experiment_name = "example_experiment" 84 | 85 | load_and_run_policy(label, experiment_name=experiment_name, max_vel=0.75, max_yaw_vel=1.0) 86 | -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/scripts/send_to_unitree.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # download docker image if it doesn't exist yet 3 | wget --directory-prefix=../docker -nc --load-cookies /tmp/cookies.txt "https://docs.google.com/uc?export=download&confirm=$(wget --quiet --save-cookies /tmp/cookies.txt --keep-session-cookies --no-check-certificate 'https://docs.google.com/uc?export=download&id=1XkVpyYyYqQQ4FcgLIDUxg-GR1WI89-XC' -O- | sed -rn 's/.*confirm=([0-9A-Za-z_]+).*/\1\n/p')&id=1XkVpyYyYqQQ4FcgLIDUxg-GR1WI89-XC" -O deployment_image.tar && rm -rf /tmp/cookies.txt 4 | 5 | #rsync -av -e ssh --exclude=*.pt --exclude=*.mp4 $PWD/../../go1_gym_deploy $PWD/../../runs $PWD/../../setup.py pi@192.168.12.1:/home/pi/go1_gym 6 | rsync -av -e ssh --exclude=*.pt --exclude=*.mp4 $PWD/../../go1_gym_deploy $PWD/../../runs $PWD/../setup.py unitree@192.168.123.15:/home/unitree/go1_gym 7 | #scp -r $PWD/../../runs pi@192.168.12.1:/home/pi/go1_gym 8 | #scp -r $PWD/../../setup.py pi@192.168.12.1:/home/pi/go1_gym 9 | -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import find_packages 2 | from distutils.core import setup 3 | 4 | setup( 5 | name='go1_gym', 6 | version='1.0.0', 7 | author='Gabriel Margolis', 8 | license="BSD-3-Clause", 9 | packages=find_packages(), 10 | author_email='gmargo@mit.edu', 11 | description='Toolkit for deployment of sim-to-real RL on the Unitree Go1.' 12 | ) 13 | -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/go1_gym_deploy/tests/__init__.py -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/tests/check_camera_msgs.py: -------------------------------------------------------------------------------- 1 | import lcm 2 | import threading 3 | import time 4 | import select 5 | 6 | import numpy as np 7 | 8 | from go1_gym_deploy.lcm_types.leg_control_data_lcmt import leg_control_data_lcmt 9 | from go1_gym_deploy.lcm_types.rc_command_lcmt import rc_command_lcmt 10 | from go1_gym_deploy.lcm_types.state_estimator_lcmt import state_estimator_lcmt 11 | from go1_gym_deploy.lcm_types.vicon_pose_lcmt import vicon_pose_lcmt 12 | from go1_gym_deploy.lcm_types.camera_message_lcmt import camera_message_lcmt 13 | from go1_gym_deploy.lcm_types.camera_message_rect_wide import camera_message_rect_wide 14 | from go1_gym_deploy.lcm_types.camera_message_rect_wide_mask import camera_message_rect_wide_mask 15 | 16 | 17 | class UnitreeLCMInspector: 18 | def __init__(self, lc): 19 | self.lc = lc 20 | 21 | self.camera_names = ["front", "bottom", "left", "right", "rear"] 22 | for cam_name in self.camera_names: 23 | self.camera_subscription = self.lc.subscribe(f"rect_image_{cam_name}", self._rect_camera_cb) 24 | for cam_name in self.camera_names: 25 | self.camera_subscription = self.lc.subscribe(f"rect_image_{cam_name}_mask", self._mask_camera_cb) 26 | 27 | self.camera_image_left = None 28 | self.camera_image_right = None 29 | self.camera_image_front = None 30 | self.camera_image_bottom = None 31 | self.camera_image_rear = None 32 | 33 | self.ts = [time.time(), time.time(), time.time(), time.time(), time.time(),] 34 | 35 | self.num_low_states = 0 36 | 37 | def _rect_camera_cb(self, channel, data): 38 | 39 | # message_types = [camera_message_rect_front, camera_message_rect_front_chin, camera_message_rect_left, 40 | # camera_message_rect_right, camera_message_rect_rear_down] 41 | # image_shapes = [(200, 200, 3), (100, 100, 3), (100, 232, 3), (100, 232, 3), (200, 200, 3)] 42 | 43 | message_types = [camera_message_rect_wide, camera_message_rect_wide, camera_message_rect_wide, camera_message_rect_wide, camera_message_rect_wide] 44 | image_shapes = [(116, 100, 3), (116, 100, 3), (116, 100, 3), (116, 100, 3), (116, 100, 3)] 45 | 46 | cam_name = channel.split("_")[-1] 47 | 48 | cam_id = self.camera_names.index(cam_name) + 1 49 | 50 | print(channel, message_types[cam_id - 1]) 51 | msg = message_types[cam_id - 1].decode(data) 52 | 53 | img = np.fromstring(msg.data, dtype=np.uint8) 54 | img = np.flip(np.flip( 55 | img.reshape((image_shapes[cam_id - 1][2], image_shapes[cam_id - 1][1], image_shapes[cam_id - 1][0])), 56 | axis=0), axis=1).transpose(1, 2, 0) 57 | 58 | if cam_id == 1: 59 | self.camera_image_front = img 60 | elif cam_id == 2: 61 | self.camera_image_bottom = img 62 | elif cam_id == 3: 63 | self.camera_image_left = img 64 | elif cam_id == 4: 65 | self.camera_image_right = img 66 | elif cam_id == 5: 67 | self.camera_image_rear = img 68 | else: 69 | print("Image received from camera with unknown ID#!") 70 | 71 | print(f"f{1. / (time.time() - self.ts[cam_id - 1])}: received py from {cam_name}!") 72 | self.ts[cam_id-1] = time.time() 73 | 74 | from PIL import Image 75 | im = Image.fromarray(img) 76 | im.save(f"{cam_name}_image.jpeg") 77 | 78 | def _mask_camera_cb(self, channel, data): 79 | 80 | message_types = [camera_message_rect_wide_mask for i in range(5)] 81 | image_shapes = [(116, 100, 1) for i in range(5)] 82 | 83 | cam_name = channel.split("_")[-2] 84 | 85 | cam_id = self.camera_names.index(cam_name) + 1 86 | 87 | print(channel, message_types[cam_id - 1]) 88 | msg = message_types[cam_id - 1].decode(data) 89 | 90 | img = np.array(list(msg.data)).astype(np.uint8) 91 | img = np.flip(np.flip( 92 | img.reshape((image_shapes[cam_id - 1][2], image_shapes[cam_id - 1][1], image_shapes[cam_id - 1][0])), 93 | axis=0), axis=1) 94 | 95 | if cam_id == 1: 96 | self.camera_image_front = img 97 | elif cam_id == 2: 98 | self.camera_image_bottom = img 99 | elif cam_id == 3: 100 | self.camera_image_left = img 101 | elif cam_id == 4: 102 | self.camera_image_right = img 103 | elif cam_id == 5: 104 | self.camera_image_rear = img 105 | else: 106 | print("Image received from camera with unknown ID#!") 107 | 108 | print(f"f{1. / (time.time() - self.ts[cam_id - 1])}: received py from {cam_name}!") 109 | self.ts[cam_id-1] = time.time() 110 | 111 | from PIL import Image 112 | # print(img[0]) 113 | im = Image.fromarray(img[0]) 114 | im.save(f"{cam_name}_mask_image.jpeg") 115 | 116 | def publish_30Hz(self): 117 | msg = camera_message_rect_wide() 118 | msg.data = [0] * 34800 119 | self.lc.publish("rect_image_rear", msg.encode()) 120 | time.sleep(1./30.) 121 | 122 | def poll(self, cb=None): 123 | t = time.time() 124 | try: 125 | while True: 126 | timeout = 0.01 127 | rfds, wfds, efds = select.select([self.lc.fileno()], [], [], timeout) 128 | if rfds: 129 | # print("message received!") 130 | self.lc.handle() 131 | # print(f'Freq {1. / (time.time() - t)} Hz'); t = time.time() 132 | else: 133 | continue 134 | # print(f'waiting for message... Freq {1. / (time.time() - t)} Hz'); t = time.time() 135 | # if cb is not None: 136 | # cb() 137 | except KeyboardInterrupt: 138 | pass 139 | 140 | def spin(self): 141 | self.run_thread = threading.Thread(target=self.poll, daemon=False) 142 | self.run_thread.start() 143 | 144 | if __name__ == "__main__": 145 | import lcm 146 | 147 | lc = lcm.LCM("udpm://239.255.76.67:7667?ttl=255") 148 | #check_lcm_msgs() 149 | print("init") 150 | insp = UnitreeLCMInspector(lc) 151 | print("polling") 152 | # insp.poll() 153 | while True: 154 | insp.publish_30Hz() 155 | -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/unitree_legged_sdk_bin/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/go1_gym_deploy/unitree_legged_sdk_bin/__init__.py -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/unitree_legged_sdk_bin/lcm_position: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/go1_gym_deploy/unitree_legged_sdk_bin/lcm_position -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/go1_gym_deploy/utils/__init__.py -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/utils/logger.py: -------------------------------------------------------------------------------- 1 | import copy 2 | import pickle as pkl 3 | 4 | import numpy as np 5 | import torch 6 | 7 | 8 | def class_to_dict(obj) -> dict: 9 | if not hasattr(obj, "__dict__"): 10 | return obj 11 | result = {} 12 | for key in dir(obj): 13 | if key.startswith("_") or key == "terrain": 14 | continue 15 | element = [] 16 | val = getattr(obj, key) 17 | if isinstance(val, list): 18 | for item in val: 19 | element.append(class_to_dict(item)) 20 | else: 21 | print(key) 22 | element = class_to_dict(val) 23 | result[key] = element 24 | return result 25 | 26 | 27 | class MultiLogger: 28 | def __init__(self): 29 | self.loggers = {} 30 | 31 | def add_robot(self, name, cfg): 32 | print(name, cfg) 33 | self.loggers[name] = EpisodeLogger(cfg) 34 | 35 | def log(self, name, info): 36 | self.loggers[name].log(info) 37 | 38 | def save(self, filename): 39 | with open(filename, 'wb') as file: 40 | logdict = {} 41 | for key in self.loggers.keys(): 42 | logdict[key] = [class_to_dict(self.loggers[key].cfg), self.loggers[key].infos] 43 | pkl.dump(logdict, file) 44 | print(f"Saved log! Number of timesteps: {[len(self.loggers[key].infos) for key in self.loggers.keys()]}; Path: {filename}") 45 | 46 | def read_metric(self, metric, robot_name=None): 47 | if robot_name is None: 48 | robot_name = list(self.loggers.keys())[0] 49 | logger = self.loggers[robot_name] 50 | 51 | metric_arr = [] 52 | for info in logger.infos: 53 | metric_arr += [info[metric]] 54 | return np.array(metric_arr) 55 | 56 | def reset(self): 57 | for key, log in self.loggers.items(): 58 | log.reset() 59 | 60 | 61 | class EpisodeLogger: 62 | def __init__(self, cfg): 63 | self.infos = [] 64 | self.cfg = cfg 65 | 66 | def log(self, info): 67 | for key in info.keys(): 68 | if isinstance(info[key], torch.Tensor): 69 | info[key] = info[key].detach().cpu().numpy() 70 | 71 | if isinstance(info[key], dict): 72 | continue 73 | elif "image" not in key: 74 | info[key] = copy.deepcopy(info[key]) 75 | 76 | self.infos += [dict(info)] 77 | 78 | def reset(self): 79 | self.infos = [] 80 | -------------------------------------------------------------------------------- /legged_gym/go1_gym_deploy/utils/network_config_unitree.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from os.path import expanduser 4 | import netifaces 5 | import sys 6 | import subprocess 7 | 8 | def get_saved_interface_name(): 9 | home = expanduser("~") 10 | name = "" 11 | try: 12 | with open(home + "/.cheetah_network.txt"): 13 | name = f.read().split()[0] 14 | except: 15 | name = "" 16 | return name 17 | 18 | def get_likely_iface(): 19 | ifs = netifaces.interfaces() 20 | print("Found {} interfaces:".format(len(ifs))) 21 | 22 | if_to_addrs = {} 23 | 24 | for i in ifs: 25 | if_to_addrs[i] = [] 26 | if netifaces.AF_INET in netifaces.ifaddresses(i).keys(): 27 | for ad in netifaces.ifaddresses(i)[netifaces.AF_INET]: 28 | if_to_addrs[i].append(ad['addr']) 29 | 30 | for i in range(len(ifs)): 31 | print(" [{}] : {} : {}".format(i, ifs[i], if_to_addrs[ifs[i]])) 32 | 33 | found_10_ip = 0 34 | selected_if = "" 35 | 36 | for i in ifs: 37 | match_string = "192.168.123." 38 | if len(if_to_addrs[i]) > 0 and if_to_addrs[i][0][:len(match_string)] == match_string: 39 | found_10_ip = found_10_ip + 1 40 | selected_if = i 41 | 42 | if found_10_ip == 0: 43 | print("None of the network adapters look correct. Make sure you have set a 10.0.0.x static ip!") 44 | return "" 45 | 46 | elif found_10_ip == 1: 47 | print("The adapter {} seems correct".format(selected_if)) 48 | return selected_if 49 | 50 | else: 51 | print("Found {} possible adapters, giving up".format(found_10_ip)) 52 | return "" 53 | 54 | def main(): 55 | name = get_saved_interface_name() 56 | if not name: 57 | print("Didn't find saved interface, searching...") 58 | name = get_likely_iface() 59 | if not name: 60 | sys.exit("Failed to find network adapter name") 61 | else: 62 | print("Found saved interface {}".format(name)) 63 | 64 | print("Setup for interface {}".format(name)) 65 | subprocess.call(['sudo', 'ifconfig', name, 'multicast']) 66 | subprocess.call(['sudo', 'route', 'add', '-net', '224.0.0.0', 'netmask', '240.0.0.0', 'dev', name]) 67 | 68 | if __name__ == "__main__": 69 | main() 70 | -------------------------------------------------------------------------------- /legged_gym/legged_gym/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | import os 32 | 33 | LEGGED_GYM_ROOT_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) 34 | LEGGED_GYM_ENVS_DIR = os.path.join(LEGGED_GYM_ROOT_DIR, 'legged_gym', 'envs') -------------------------------------------------------------------------------- /legged_gym/legged_gym/envs/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | from legged_gym import LEGGED_GYM_ROOT_DIR, LEGGED_GYM_ENVS_DIR 32 | from legged_gym.envs.a1.a1_config import A1RoughCfg, A1RoughCfgPPO 33 | from .base.legged_robot import LeggedRobot 34 | from .anymal_c.anymal import Anymal 35 | from .anymal_c.mixed_terrains.anymal_c_rough_config import AnymalCRoughCfg, AnymalCRoughCfgPPO 36 | from .anymal_c.flat.anymal_c_flat_config import AnymalCFlatCfg, AnymalCFlatCfgPPO 37 | from .anymal_b.anymal_b_config import AnymalBRoughCfg, AnymalBRoughCfgPPO 38 | from .cassie.cassie import Cassie 39 | from .cassie.cassie_config import CassieRoughCfg, CassieRoughCfgPPO 40 | from .a1.a1_config import A1RoughCfg, A1RoughCfgPPO 41 | from .go1.go1_config import Go1RoughCfg, Go1RoughCfgPPO 42 | 43 | 44 | import os 45 | 46 | from legged_gym.utils.task_registry import task_registry 47 | 48 | task_registry.register( "anymal_c_rough", Anymal, AnymalCRoughCfg(), AnymalCRoughCfgPPO() ) 49 | task_registry.register( "anymal_c_flat", Anymal, AnymalCFlatCfg(), AnymalCFlatCfgPPO() ) 50 | task_registry.register( "anymal_b", Anymal, AnymalBRoughCfg(), AnymalBRoughCfgPPO() ) 51 | task_registry.register( "a1", LeggedRobot, A1RoughCfg(), A1RoughCfgPPO() ) 52 | task_registry.register( "cassie", Cassie, CassieRoughCfg(), CassieRoughCfgPPO() ) 53 | task_registry.register( "go1", LeggedRobot, Go1RoughCfg(), Go1RoughCfgPPO() ) 54 | -------------------------------------------------------------------------------- /legged_gym/legged_gym/envs/a1/a1_config.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | from legged_gym.envs.base.legged_robot_config import LeggedRobotCfg, LeggedRobotCfgPPO 32 | 33 | class A1RoughCfg( LeggedRobotCfg ): 34 | class init_state( LeggedRobotCfg.init_state ): 35 | pos = [0.0, 0.0, 0.42] # x,y,z [m] 36 | default_joint_angles = { # = target angles [rad] when action = 0.0 37 | 'FL_hip_joint': 0.1, # [rad] 38 | 'RL_hip_joint': 0.1, # [rad] 39 | 'FR_hip_joint': -0.1 , # [rad] 40 | 'RR_hip_joint': -0.1, # [rad] 41 | 42 | 'FL_thigh_joint': 0.8, # [rad] 43 | 'RL_thigh_joint': 1., # [rad] 44 | 'FR_thigh_joint': 0.8, # [rad] 45 | 'RR_thigh_joint': 1., # [rad] 46 | 47 | 'FL_calf_joint': -1.5, # [rad] 48 | 'RL_calf_joint': -1.5, # [rad] 49 | 'FR_calf_joint': -1.5, # [rad] 50 | 'RR_calf_joint': -1.5, # [rad] 51 | } 52 | 53 | class control( LeggedRobotCfg.control ): 54 | # PD Drive parameters: 55 | control_type = 'P' 56 | stiffness = {'joint': 20.} # [N*m/rad] 57 | damping = {'joint': 0.5} # [N*m*s/rad] 58 | # action scale: target angle = actionScale * action + defaultAngle 59 | action_scale = 0.25 60 | # decimation: Number of control action updates @ sim DT per policy DT 61 | decimation = 4 62 | 63 | class asset( LeggedRobotCfg.asset ): 64 | file = '{LEGGED_GYM_ROOT_DIR}/resources/robots/a1/urdf/a1.urdf' 65 | name = "a1" 66 | foot_name = "foot" 67 | penalize_contacts_on = ["thigh", "calf"] 68 | terminate_after_contacts_on = ["base"] 69 | self_collisions = 1 # 1 to disable, 0 to enable...bitwise filter 70 | 71 | class rewards( LeggedRobotCfg.rewards ): 72 | soft_dof_pos_limit = 0.9 73 | base_height_target = 0.25 74 | class scales( LeggedRobotCfg.rewards.scales ): 75 | # torques = -0.0002 76 | dof_pos_limits = -10.0 77 | 78 | class A1RoughCfgPPO( LeggedRobotCfgPPO ): 79 | class algorithm( LeggedRobotCfgPPO.algorithm ): 80 | entropy_coef = 0.01 81 | class runner( LeggedRobotCfgPPO.runner ): 82 | run_name = '' 83 | experiment_name = 'rough_a1' 84 | 85 | -------------------------------------------------------------------------------- /legged_gym/legged_gym/envs/anymal_b/anymal_b_config.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | from legged_gym.envs import AnymalCRoughCfg, AnymalCRoughCfgPPO 32 | 33 | class AnymalBRoughCfg( AnymalCRoughCfg ): 34 | class asset( AnymalCRoughCfg.asset ): 35 | file = '{LEGGED_GYM_ROOT_DIR}/resources/robots/anymal_b/urdf/anymal_b.urdf' 36 | name = "anymal_b" 37 | foot_name = 'FOOT' 38 | class rewards( AnymalCRoughCfg.rewards ): 39 | class scales ( AnymalCRoughCfg.rewards.scales ): 40 | pass 41 | 42 | class AnymalBRoughCfgPPO( AnymalCRoughCfgPPO ): 43 | class runner ( AnymalCRoughCfgPPO.runner): 44 | run_name = '' 45 | experiment_name = 'rough_anymal_b' 46 | load_run = -1 -------------------------------------------------------------------------------- /legged_gym/legged_gym/envs/anymal_c/anymal.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | from time import time 32 | import numpy as np 33 | import os 34 | 35 | from isaacgym.torch_utils import * 36 | from isaacgym import gymtorch, gymapi, gymutil 37 | 38 | import torch 39 | # from torch.tensor import Tensor 40 | from typing import Tuple, Dict 41 | 42 | from legged_gym.envs import LeggedRobot 43 | from legged_gym import LEGGED_GYM_ROOT_DIR 44 | from .mixed_terrains.anymal_c_rough_config import AnymalCRoughCfg 45 | 46 | class Anymal(LeggedRobot): 47 | cfg : AnymalCRoughCfg 48 | def __init__(self, cfg, sim_params, physics_engine, sim_device, headless): 49 | super().__init__(cfg, sim_params, physics_engine, sim_device, headless) 50 | 51 | # load actuator network 52 | if self.cfg.control.use_actuator_network: 53 | actuator_network_path = self.cfg.control.actuator_net_file.format(LEGGED_GYM_ROOT_DIR=LEGGED_GYM_ROOT_DIR) 54 | self.actuator_network = torch.jit.load(actuator_network_path).to(self.device) 55 | 56 | def reset_idx(self, env_ids): 57 | super().reset_idx(env_ids) 58 | # Additionaly empty actuator network hidden states 59 | self.sea_hidden_state_per_env[:, env_ids] = 0. 60 | self.sea_cell_state_per_env[:, env_ids] = 0. 61 | 62 | def _init_buffers(self): 63 | super()._init_buffers() 64 | # Additionally initialize actuator network hidden state tensors 65 | self.sea_input = torch.zeros(self.num_envs*self.num_actions, 1, 2, device=self.device, requires_grad=False) 66 | self.sea_hidden_state = torch.zeros(2, self.num_envs*self.num_actions, 8, device=self.device, requires_grad=False) 67 | self.sea_cell_state = torch.zeros(2, self.num_envs*self.num_actions, 8, device=self.device, requires_grad=False) 68 | self.sea_hidden_state_per_env = self.sea_hidden_state.view(2, self.num_envs, self.num_actions, 8) 69 | self.sea_cell_state_per_env = self.sea_cell_state.view(2, self.num_envs, self.num_actions, 8) 70 | 71 | def _compute_torques(self, actions): 72 | # Choose between pd controller and actuator network 73 | if self.cfg.control.use_actuator_network: 74 | with torch.inference_mode(): 75 | self.sea_input[:, 0, 0] = (actions * self.cfg.control.action_scale + self.default_dof_pos - self.dof_pos).flatten() 76 | self.sea_input[:, 0, 1] = self.dof_vel.flatten() 77 | torques, (self.sea_hidden_state[:], self.sea_cell_state[:]) = self.actuator_network(self.sea_input, (self.sea_hidden_state, self.sea_cell_state)) 78 | return torques 79 | else: 80 | # pd controller 81 | return super()._compute_torques(actions) -------------------------------------------------------------------------------- /legged_gym/legged_gym/envs/anymal_c/flat/anymal_c_flat_config.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | from legged_gym.envs import AnymalCRoughCfg, AnymalCRoughCfgPPO 32 | 33 | class AnymalCFlatCfg( AnymalCRoughCfg ): 34 | class env( AnymalCRoughCfg.env ): 35 | num_observations = 48 36 | 37 | class terrain( AnymalCRoughCfg.terrain ): 38 | mesh_type = 'plane' 39 | measure_heights = False 40 | 41 | class asset( AnymalCRoughCfg.asset ): 42 | self_collisions = 0 # 1 to disable, 0 to enable...bitwise filter 43 | 44 | class rewards( AnymalCRoughCfg.rewards ): 45 | max_contact_force = 350. 46 | class scales ( AnymalCRoughCfg.rewards.scales ): 47 | orientation = -5.0 48 | torques = -0.000025 49 | feet_air_time = 2. 50 | # feet_contact_forces = -0.01 51 | 52 | class commands( AnymalCRoughCfg.commands ): 53 | heading_command = False 54 | resampling_time = 4. 55 | class ranges( AnymalCRoughCfg.commands.ranges ): 56 | ang_vel_yaw = [-1.5, 1.5] 57 | 58 | class domain_rand( AnymalCRoughCfg.domain_rand ): 59 | friction_range = [0., 1.5] # on ground planes the friction combination mode is averaging, i.e total friction = (foot_friction + 1.)/2. 60 | 61 | class AnymalCFlatCfgPPO( AnymalCRoughCfgPPO ): 62 | class policy( AnymalCRoughCfgPPO.policy ): 63 | actor_hidden_dims = [128, 64, 32] 64 | critic_hidden_dims = [128, 64, 32] 65 | activation = 'elu' # can be elu, relu, selu, crelu, lrelu, tanh, sigmoid 66 | 67 | class algorithm( AnymalCRoughCfgPPO.algorithm): 68 | entropy_coef = 0.01 69 | 70 | class runner ( AnymalCRoughCfgPPO.runner): 71 | run_name = '' 72 | experiment_name = 'flat_anymal_c' 73 | load_run = -1 74 | max_iterations = 300 75 | -------------------------------------------------------------------------------- /legged_gym/legged_gym/envs/anymal_c/mixed_terrains/anymal_c_rough_config.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | from legged_gym.envs.base.legged_robot_config import LeggedRobotCfg, LeggedRobotCfgPPO 32 | 33 | class AnymalCRoughCfg( LeggedRobotCfg ): 34 | class env( LeggedRobotCfg.env ): 35 | num_envs = 4096 36 | num_actions = 12 37 | 38 | class terrain( LeggedRobotCfg.terrain ): 39 | mesh_type = 'trimesh' 40 | 41 | class init_state( LeggedRobotCfg.init_state ): 42 | pos = [0.0, 0.0, 0.6] # x,y,z [m] 43 | default_joint_angles = { # = target angles [rad] when action = 0.0 44 | "LF_HAA": 0.0, 45 | "LH_HAA": 0.0, 46 | "RF_HAA": -0.0, 47 | "RH_HAA": -0.0, 48 | 49 | "LF_HFE": 0.4, 50 | "LH_HFE": -0.4, 51 | "RF_HFE": 0.4, 52 | "RH_HFE": -0.4, 53 | 54 | "LF_KFE": -0.8, 55 | "LH_KFE": 0.8, 56 | "RF_KFE": -0.8, 57 | "RH_KFE": 0.8, 58 | } 59 | 60 | class control( LeggedRobotCfg.control ): 61 | # PD Drive parameters: 62 | stiffness = {'HAA': 80., 'HFE': 80., 'KFE': 80.} # [N*m/rad] 63 | damping = {'HAA': 2., 'HFE': 2., 'KFE': 2.} # [N*m*s/rad] 64 | # action scale: target angle = actionScale * action + defaultAngle 65 | action_scale = 0.5 66 | # decimation: Number of control action updates @ sim DT per policy DT 67 | decimation = 4 68 | use_actuator_network = True 69 | actuator_net_file = "{LEGGED_GYM_ROOT_DIR}/resources/actuator_nets/anydrive_v3_lstm.pt" 70 | 71 | class asset( LeggedRobotCfg.asset ): 72 | file = "{LEGGED_GYM_ROOT_DIR}/resources/robots/anymal_c/urdf/anymal_c.urdf" 73 | name = "anymal_c" 74 | foot_name = "FOOT" 75 | penalize_contacts_on = ["SHANK", "THIGH"] 76 | terminate_after_contacts_on = ["base"] 77 | self_collisions = 1 # 1 to disable, 0 to enable...bitwise filter 78 | 79 | class domain_rand( LeggedRobotCfg.domain_rand): 80 | randomize_base_mass = True 81 | added_mass_range = [-5., 5.] 82 | 83 | class rewards( LeggedRobotCfg.rewards ): 84 | base_height_target = 0.5 85 | max_contact_force = 500. 86 | only_positive_rewards = True 87 | class scales( LeggedRobotCfg.rewards.scales ): 88 | pass 89 | 90 | class AnymalCRoughCfgPPO( LeggedRobotCfgPPO ): 91 | class runner( LeggedRobotCfgPPO.runner ): 92 | run_name = '' 93 | experiment_name = 'rough_anymal_c' 94 | load_run = -1 95 | -------------------------------------------------------------------------------- /legged_gym/legged_gym/envs/base/base_config.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | import inspect 32 | 33 | class BaseConfig: 34 | def __init__(self) -> None: 35 | """ Initializes all member classes recursively. Ignores all namse starting with '__' (buit-in methods).""" 36 | self.init_member_classes(self) 37 | 38 | @staticmethod 39 | def init_member_classes(obj): 40 | # iterate over all attributes names 41 | for key in dir(obj): 42 | # disregard builtin attributes 43 | # if key.startswith("__"): 44 | if key=="__class__": 45 | continue 46 | # get the corresponding attribute object 47 | var = getattr(obj, key) 48 | # check if it the attribute is a class 49 | if inspect.isclass(var): 50 | # instantate the class 51 | i_var = var() 52 | # set the attribute to the instance instead of the type 53 | setattr(obj, key, i_var) 54 | # recursively init members of the attribute 55 | BaseConfig.init_member_classes(i_var) -------------------------------------------------------------------------------- /legged_gym/legged_gym/envs/base/base_task.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | import sys 32 | from isaacgym import gymapi 33 | from isaacgym import gymutil 34 | import numpy as np 35 | import torch 36 | 37 | # Base class for RL tasks 38 | class BaseTask(): 39 | 40 | def __init__(self, cfg, sim_params, physics_engine, sim_device, headless): 41 | self.gym = gymapi.acquire_gym() 42 | 43 | self.sim_params = sim_params 44 | self.physics_engine = physics_engine 45 | self.sim_device = sim_device 46 | sim_device_type, self.sim_device_id = gymutil.parse_device_str(self.sim_device) 47 | self.headless = headless 48 | 49 | # env device is GPU only if sim is on GPU and use_gpu_pipeline=True, otherwise returned tensors are copied to CPU by physX. 50 | if sim_device_type=='cuda' and sim_params.use_gpu_pipeline: 51 | self.device = self.sim_device 52 | else: 53 | self.device = 'cpu' 54 | 55 | # graphics device for rendering, -1 for no rendering 56 | self.graphics_device_id = self.sim_device_id 57 | if self.headless == True: 58 | self.graphics_device_id = -1 59 | 60 | self.num_envs = cfg.env.num_envs 61 | self.num_obs = cfg.env.num_observations 62 | self.num_obs_hist = cfg.env.num_obs_hist 63 | self.num_privileged_obs = cfg.env.num_privileged_obs 64 | self.num_actions = cfg.env.num_actions 65 | 66 | # optimization flags for pytorch JIT 67 | torch._C._jit_set_profiling_mode(False) 68 | torch._C._jit_set_profiling_executor(False) 69 | 70 | # allocate buffers 71 | self.obs_buf = torch.zeros(self.num_envs, self.num_obs, device=self.device, dtype=torch.float) 72 | self.obs_hist_buf = torch.zeros(self.num_envs, self.num_obs_hist*self.num_obs, device = self.device, dtype=torch.float) 73 | self.rew_buf = torch.zeros(self.num_envs, device=self.device, dtype=torch.float) 74 | self.reset_buf = torch.ones(self.num_envs, device=self.device, dtype=torch.long) 75 | self.episode_length_buf = torch.zeros(self.num_envs, device=self.device, dtype=torch.long) 76 | self.time_out_buf = torch.zeros(self.num_envs, device=self.device, dtype=torch.bool) 77 | if self.num_privileged_obs is not None: 78 | self.privileged_obs_buf = torch.zeros(self.num_envs, self.num_privileged_obs, device=self.device, dtype=torch.float) 79 | else: 80 | self.privileged_obs_buf = None 81 | # self.num_privileged_obs = self.num_obs 82 | self.prev_privileged_obs_buf = torch.zeros(self.num_envs, self.num_privileged_obs, device=self.device, dtype=torch.float) 83 | self.disturbance_force = torch.zeros((self.num_envs,2),device=self.device,dtype=torch.float) 84 | 85 | self.extras = {} 86 | 87 | # create envs, sim and viewer 88 | self.create_sim() 89 | self.gym.prepare_sim(self.sim) 90 | 91 | # todo: read from config 92 | self.enable_viewer_sync = True 93 | self.viewer = None 94 | 95 | # if running with a viewer, set up keyboard shortcuts and camera 96 | if self.headless == False: 97 | # subscribe to keyboard shortcuts 98 | self.viewer = self.gym.create_viewer( 99 | self.sim, gymapi.CameraProperties()) 100 | self.gym.subscribe_viewer_keyboard_event( 101 | self.viewer, gymapi.KEY_ESCAPE, "QUIT") 102 | self.gym.subscribe_viewer_keyboard_event( 103 | self.viewer, gymapi.KEY_V, "toggle_viewer_sync") 104 | 105 | def get_observations(self): 106 | return self.obs_buf, self.obs_hist_buf 107 | 108 | def get_privileged_observations(self): 109 | return self.privileged_obs_buf,self.prev_privileged_obs_buf 110 | 111 | def reset_idx(self, env_ids): 112 | """Reset selected robots""" 113 | raise NotImplementedError 114 | 115 | def reset(self): 116 | """ Reset all robots""" 117 | self.reset_idx(torch.arange(self.num_envs, device=self.device)) 118 | obs, privileged_obs, _, _, _, _, _ = self.step(torch.zeros(self.num_envs, self.num_actions, device=self.device, requires_grad=False)) 119 | obs_hist = torch.zeros(self.num_envs, self.num_obs_hist*self.num_obs, device = self.device, dtype=torch.float) 120 | prev_privileged_obs = torch.zeros(self.num_envs, self.num_privileged_obs, device=self.device, dtype=torch.float) 121 | return obs, privileged_obs, prev_privileged_obs, obs_hist 122 | 123 | def step(self, actions): 124 | raise NotImplementedError 125 | 126 | def render(self, sync_frame_time=True): 127 | if self.viewer: 128 | # check for window closed 129 | if self.gym.query_viewer_has_closed(self.viewer): 130 | sys.exit() 131 | 132 | # check for keyboard events 133 | for evt in self.gym.query_viewer_action_events(self.viewer): 134 | if evt.action == "QUIT" and evt.value > 0: 135 | sys.exit() 136 | elif evt.action == "toggle_viewer_sync" and evt.value > 0: 137 | self.enable_viewer_sync = not self.enable_viewer_sync 138 | 139 | # fetch results 140 | if self.device != 'cpu': 141 | self.gym.fetch_results(self.sim, True) 142 | 143 | # step graphics 144 | if self.enable_viewer_sync: 145 | self.gym.step_graphics(self.sim) 146 | self.gym.draw_viewer(self.viewer, self.sim, True) 147 | if sync_frame_time: 148 | self.gym.sync_frame_time(self.sim) 149 | else: 150 | self.gym.poll_viewer_events(self.viewer) -------------------------------------------------------------------------------- /legged_gym/legged_gym/envs/cassie/cassie.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | from time import time 32 | import numpy as np 33 | import os 34 | 35 | from isaacgym.torch_utils import * 36 | from isaacgym import gymtorch, gymapi, gymutil 37 | 38 | import torch 39 | from typing import Tuple, Dict 40 | from legged_gym.envs import LeggedRobot 41 | 42 | class Cassie(LeggedRobot): 43 | def _reward_no_fly(self): 44 | contacts = self.contact_forces[:, self.feet_indices, 2] > 0.1 45 | single_contact = torch.sum(1.*contacts, dim=1)==1 46 | return 1.*single_contact -------------------------------------------------------------------------------- /legged_gym/legged_gym/envs/cassie/cassie_config.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | from legged_gym.envs.base.legged_robot_config import LeggedRobotCfg, LeggedRobotCfgPPO 32 | 33 | class CassieRoughCfg( LeggedRobotCfg ): 34 | class env( LeggedRobotCfg.env): 35 | num_envs = 4096 36 | num_observations = 169 37 | num_actions = 12 38 | 39 | 40 | class terrain( LeggedRobotCfg.terrain): 41 | measured_points_x = [-0.5, -0.4, -0.3, -0.2, -0.1, 0., 0.1, 0.2, 0.3, 0.4, 0.5] # 1mx1m rectangle (without center line) 42 | measured_points_y = [-0.5, -0.4, -0.3, -0.2, -0.1, 0., 0.1, 0.2, 0.3, 0.4, 0.5] 43 | 44 | class init_state( LeggedRobotCfg.init_state ): 45 | pos = [0.0, 0.0, 1.] # x,y,z [m] 46 | default_joint_angles = { # = target angles [rad] when action = 0.0 47 | 'hip_abduction_left': 0.1, 48 | 'hip_rotation_left': 0., 49 | 'hip_flexion_left': 1., 50 | 'thigh_joint_left': -1.8, 51 | 'ankle_joint_left': 1.57, 52 | 'toe_joint_left': -1.57, 53 | 54 | 'hip_abduction_right': -0.1, 55 | 'hip_rotation_right': 0., 56 | 'hip_flexion_right': 1., 57 | 'thigh_joint_right': -1.8, 58 | 'ankle_joint_right': 1.57, 59 | 'toe_joint_right': -1.57 60 | } 61 | 62 | class control( LeggedRobotCfg.control ): 63 | # PD Drive parameters: 64 | stiffness = { 'hip_abduction': 100.0, 'hip_rotation': 100.0, 65 | 'hip_flexion': 200., 'thigh_joint': 200., 'ankle_joint': 200., 66 | 'toe_joint': 40.} # [N*m/rad] 67 | damping = { 'hip_abduction': 3.0, 'hip_rotation': 3.0, 68 | 'hip_flexion': 6., 'thigh_joint': 6., 'ankle_joint': 6., 69 | 'toe_joint': 1.} # [N*m*s/rad] # [N*m*s/rad] 70 | # action scale: target angle = actionScale * action + defaultAngle 71 | action_scale = 0.5 72 | # decimation: Number of control action updates @ sim DT per policy DT 73 | decimation = 4 74 | 75 | class asset( LeggedRobotCfg.asset ): 76 | file = '{LEGGED_GYM_ROOT_DIR}/resources/robots/cassie/urdf/cassie.urdf' 77 | name = "cassie" 78 | foot_name = 'toe' 79 | terminate_after_contacts_on = ['pelvis'] 80 | flip_visual_attachments = False 81 | self_collisions = 1 # 1 to disable, 0 to enable...bitwise filter 82 | 83 | class rewards( LeggedRobotCfg.rewards ): 84 | soft_dof_pos_limit = 0.95 85 | soft_dof_vel_limit = 0.9 86 | soft_torque_limit = 0.9 87 | max_contact_force = 300. 88 | only_positive_rewards = False 89 | class scales( LeggedRobotCfg.rewards.scales ): 90 | termination = -200. 91 | tracking_ang_vel = 1.0 92 | torques = -5.e-6 93 | dof_acc = -2.e-7 94 | lin_vel_z = -0.5 95 | feet_air_time = 5. 96 | dof_pos_limits = -1. 97 | no_fly = 0.25 98 | dof_vel = -0.0 99 | ang_vel_xy = -0.0 100 | feet_contact_forces = -0. 101 | 102 | class CassieRoughCfgPPO( LeggedRobotCfgPPO ): 103 | 104 | class runner( LeggedRobotCfgPPO.runner ): 105 | run_name = '' 106 | experiment_name = 'rough_cassie' 107 | 108 | class algorithm( LeggedRobotCfgPPO.algorithm): 109 | entropy_coef = 0.01 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /legged_gym/legged_gym/envs/go1/go1_config.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | from legged_gym.envs.base.legged_robot_config import LeggedRobotCfg, LeggedRobotCfgPPO 32 | 33 | class Go1RoughCfg( LeggedRobotCfg ): 34 | class init_state( LeggedRobotCfg.init_state ): 35 | pos = [0.0, 0.0, 0.34] # x,y,z [m] 36 | default_joint_angles = { # = target angles [rad] when action = 0.0 37 | 'FL_hip_joint': 0.1, # [rad] 38 | 'RL_hip_joint': 0.1, # [rad] 39 | 'FR_hip_joint': -0.1 , # [rad] 40 | 'RR_hip_joint': -0.1, # [rad] 41 | 42 | 'FL_thigh_joint': 0.8, # [rad] 43 | 'RL_thigh_joint': 1., # [rad] 44 | 'FR_thigh_joint': 0.8, # [rad] 45 | 'RR_thigh_joint': 1., # [rad] 46 | 47 | 'FL_calf_joint': -1.5, # [rad] 48 | 'RL_calf_joint': -1.5, # [rad] 49 | 'FR_calf_joint': -1.5, # [rad] 50 | 'RR_calf_joint': -1.5, # [rad] 51 | } 52 | 53 | class control( LeggedRobotCfg.control ): 54 | # PD Drive parameters: 55 | control_type = 'P' 56 | stiffness = {'joint': 28.} # [N*m/rad] 57 | damping = {'joint': 0.7} # [N*m*s/rad] 58 | # action scale: target angle = actionScale * action + defaultAngle 59 | action_scale = 0.25 60 | # decimation: Number of control action updates @ sim DT per policy DT 61 | decimation = 4 62 | 63 | class asset( LeggedRobotCfg.asset ): 64 | file = '{LEGGED_GYM_ROOT_DIR}/resources/robots/go1/urdf/go1.urdf' 65 | name = "go1" 66 | foot_name = "foot" 67 | penalize_contacts_on = ["thigh", "calf"] 68 | terminate_after_contacts_on = ["base"] 69 | self_collisions = 1 # 1 to disable, 0 to enable...bitwise filter 70 | 71 | class rewards( LeggedRobotCfg.rewards ): 72 | soft_dof_pos_limit = 0.9 73 | base_height_target = 0.30 74 | # class scales( LeggedRobotCfg.rewards.scales ): 75 | # #torques = -0.0002 76 | # # dof_pos_limits = -10.0 77 | # # base_height = -30. 78 | 79 | class Go1RoughCfgPPO( LeggedRobotCfgPPO ): 80 | class algorithm( LeggedRobotCfgPPO.algorithm ): 81 | entropy_coef = 0.01 82 | class runner( LeggedRobotCfgPPO.runner ): 83 | run_name = '' 84 | experiment_name = 'rough_go1' 85 | 86 | -------------------------------------------------------------------------------- /legged_gym/legged_gym/envs/wrappers/history_wrapper.py: -------------------------------------------------------------------------------- 1 | from gym.core import Env 2 | import isaacgym 3 | assert isaacgym 4 | import torch 5 | import gym 6 | from base.legged_robot_config import LeggedRobotCfg 7 | 8 | class HistoryWrapper(gym.Wrapper): 9 | def __init__(self, env): 10 | super().__init__(env) 11 | self.env = env 12 | self.obs_history_length = self.env.LeggedRobotCfg.env.num_obs_hist 13 | self.num_obs_history = self.obs_history_length * self.num_obs 14 | self.obs_history = torch.zeros(self.env.num_envs, self.num_obs_history, dtype=torch.float, device=self.env.device, requires_grad=False) 15 | self.num_privileged_obs = self.num_privileged_obs 16 | 17 | 18 | def step(self,actions): 19 | obs,rew,done,info = self.env.step(actions) 20 | priveleged_obs = info["priveleged_obs"] 21 | self.obs_history = torch.cat((self.obs_history[:, self.env.num_obs:], obs), dim=-1) 22 | return {'obs': obs, 'privileged_obs': priveleged_obs, 'obs_history': self.obs_history}, rew, done, info 23 | 24 | 25 | def get_observations(self): 26 | obs = self.env.get_observations() 27 | privileged_obs = self.env.get_privileged_observations() 28 | self.obs_history = torch.cat((self.obs_history[:, self.env.num_obs:], obs), dim=-1) 29 | return {'obs': obs, 'privileged_obs': privileged_obs, 'obs_history': self.obs_history} 30 | 31 | 32 | def reset_idx(self, env_ids): 33 | ret = super().reset_idx(env_ids) 34 | self.obs_history[env_ids, :] = 0 35 | return ret 36 | 37 | 38 | def reset(self): 39 | ret = super().reset() 40 | privileged_obs = self.env.get_privileged_observations() 41 | self.obs_history[:, :] = 0 42 | return {"obs": ret, "privileged_obs": privileged_obs, "obs_history": self.obs_history} 43 | -------------------------------------------------------------------------------- /legged_gym/legged_gym/scripts/play.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | from legged_gym import LEGGED_GYM_ROOT_DIR 32 | import os 33 | 34 | import isaacgym 35 | from legged_gym.envs import * 36 | from legged_gym.utils import get_args, export_policy_as_jit, task_registry, Logger 37 | from legged_gym.utils.helpers import export_policy_as_jit_actor,export_policy_as_jit_encoder,class_to_dict 38 | 39 | import numpy as np 40 | import torch 41 | import pickle 42 | 43 | 44 | def play(args): 45 | env_cfg, train_cfg = task_registry.get_cfgs(name=args.task) 46 | class_to_dict(env_cfg) 47 | class_to_dict(train_cfg) 48 | 49 | with open('env_cfg.pkl', 'wb') as f: 50 | pickle.dump(class_to_dict(env_cfg), f) 51 | with open('train_cfg.pkl', 'wb') as f: 52 | pickle.dump(train_cfg, f) 53 | # override some parameters for testing 54 | env_cfg.env.num_envs = min(env_cfg.env.num_envs, 50) 55 | env_cfg.terrain.num_rows = 5 56 | env_cfg.terrain.num_cols = 5 57 | env_cfg.terrain.curriculum = False 58 | env_cfg.noise.add_noise = False 59 | env_cfg.domain_rand.randomize_friction = False 60 | env_cfg.domain_rand.push_robots = False 61 | 62 | # prepare environment 63 | env, _ = task_registry.make_env(name=args.task, args=args, env_cfg=env_cfg) 64 | obs,obs_hist = env.get_observations() 65 | # load policy 66 | train_cfg.runner.resume = True 67 | ppo_runner, train_cfg = task_registry.make_alg_runner(env=env, name=args.task, args=args, train_cfg=train_cfg) 68 | policy = ppo_runner.get_inference_policy(device=env.device) 69 | 70 | # export policy as a jit module (used to run it from C++) 71 | if EXPORT_POLICY: 72 | path = os.path.join(LEGGED_GYM_ROOT_DIR, 'logs', train_cfg.runner.experiment_name, 'exported', 'policies') 73 | export_policy_as_jit_actor(ppo_runner.alg.actor_critic, path) 74 | export_policy_as_jit_encoder(ppo_runner.alg.actor_critic,path) 75 | print('Exported policy as jit script to: ', path) 76 | 77 | logger = Logger(env.dt) 78 | robot_index = 0 # which robot is used for logging 79 | joint_index = 1 # which joint is used for logging 80 | stop_state_log = 1000 # number of steps before plotting states 81 | stop_rew_log = env.max_episode_length + 1 # number of steps before print average episode rewards 82 | camera_position = np.array(env_cfg.viewer.pos, dtype=np.float64) 83 | camera_vel = np.array([1., 1., 0.]) 84 | camera_direction = np.array(env_cfg.viewer.lookat) - np.array(env_cfg.viewer.pos) 85 | img_idx = 0 86 | 87 | for i in range(10*int(env.max_episode_length)): 88 | actions = policy(obs.detach(),obs_hist.detach()) 89 | obs, _, _, obs_hist, rews, dones, infos = env.step(actions.detach()) 90 | if RECORD_FRAMES: 91 | if i % 2: 92 | filename = os.path.join(LEGGED_GYM_ROOT_DIR, 'logs', train_cfg.runner.experiment_name, 'exported', 'frames', f"{img_idx}.png") 93 | env.gym.write_viewer_image_to_file(env.viewer, filename) 94 | img_idx += 1 95 | if MOVE_CAMERA: 96 | camera_position += camera_vel * env.dt 97 | env.set_camera(camera_position, camera_position + camera_direction) 98 | 99 | if i < stop_state_log: 100 | logger.log_states( 101 | { 102 | 'dof_pos_target': actions[robot_index, joint_index].item() * env.cfg.control.action_scale, 103 | 'dof_pos': env.dof_pos[robot_index, joint_index].item(), 104 | 'dof_vel': env.dof_vel[robot_index, joint_index].item(), 105 | 'dof_torque': env.torques[robot_index, joint_index].item(), 106 | 'command_x': env.commands[robot_index, 0].item(), 107 | 'command_y': env.commands[robot_index, 1].item(), 108 | 'command_yaw': env.commands[robot_index, 2].item(), 109 | 'base_vel_x': env.base_lin_vel[robot_index, 0].item(), 110 | 'base_vel_y': env.base_lin_vel[robot_index, 1].item(), 111 | 'base_vel_z': env.base_lin_vel[robot_index, 2].item(), 112 | 'base_vel_yaw': env.base_ang_vel[robot_index, 2].item(), 113 | 'contact_forces_z': env.contact_forces[robot_index, env.feet_indices, 2].cpu().numpy(), 114 | 'dof_pos_0': env.dof_pos[robot_index, 0].item(), 115 | 'dof_pos_1': env.dof_pos[robot_index, 1].item(), 116 | 'dof_pos_2': env.dof_pos[robot_index, 2].item(), 117 | 'dof_pos_3': env.dof_pos[robot_index, 3].item(), 118 | 'dof_pos_4': env.dof_pos[robot_index, 4].item(), 119 | 'dof_pos_5': env.dof_pos[robot_index, 5].item(), 120 | 'dof_pos_6': env.dof_pos[robot_index, 6].item(), 121 | 'dof_pos_7': env.dof_pos[robot_index, 7].item(), 122 | 'dof_pos_8': env.dof_pos[robot_index, 8].item(), 123 | 'dof_pos_9': env.dof_pos[robot_index, 9].item(), 124 | 'dof_pos_10': env.dof_pos[robot_index, 10].item(), 125 | 'dof_pos_11': env.dof_pos[robot_index, 11].item(), 126 | 127 | } 128 | ) 129 | elif i==stop_state_log: 130 | logger.plot_states() 131 | if 0 < i < stop_rew_log: 132 | if infos["episode"]: 133 | num_episodes = torch.sum(env.reset_buf).item() 134 | if num_episodes>0: 135 | logger.log_rewards(infos["episode"], num_episodes) 136 | elif i==stop_rew_log: 137 | logger.print_rewards() 138 | 139 | if __name__ == '__main__': 140 | EXPORT_POLICY = True 141 | RECORD_FRAMES = False 142 | MOVE_CAMERA = False 143 | args = get_args() 144 | play(args) 145 | -------------------------------------------------------------------------------- /legged_gym/legged_gym/scripts/stand_still.py: -------------------------------------------------------------------------------- 1 | from legged_gym import LEGGED_GYM_ROOT_DIR 2 | import os 3 | 4 | import isaacgym 5 | from legged_gym.envs import * 6 | from legged_gym.utils import get_args, export_policy_as_jit, task_registry, Logger 7 | 8 | import numpy as np 9 | import torch 10 | 11 | 12 | def play(args): 13 | env_cfg, train_cfg = task_registry.get_cfgs(name=args.task) 14 | # override some parameters for testing 15 | env_cfg.env.num_envs = min(env_cfg.env.num_envs, 50) 16 | env_cfg.terrain.num_rows = 5 17 | env_cfg.terrain.num_cols = 5 18 | env_cfg.terrain.curriculum = False 19 | env_cfg.noise.add_noise = False 20 | env_cfg.domain_rand.randomize_friction = False 21 | env_cfg.domain_rand.push_robots = False 22 | 23 | # prepare environment 24 | env, _ = task_registry.make_env(name=args.task, args=args, env_cfg=env_cfg) 25 | obs,obs_hist = env.get_observations() 26 | # load policy 27 | # train_cfg.runner.resume = True 28 | # ppo_runner, train_cfg = task_registry.make_alg_runner(env=env, name=args.task, args=args, train_cfg=train_cfg) 29 | # policy = ppo_runner.get_inference_policy(device=env.device) 30 | 31 | # export policy as a jit module (used to run it from C++) 32 | # if EXPORT_POLICY: 33 | # path = os.path.join(LEGGED_GYM_ROOT_DIR, 'logs', train_cfg.runner.experiment_name, 'exported', 'policies') 34 | # export_policy_as_jit(ppo_runner.alg.actor_critic, path) 35 | # print('Exported policy as jit script to: ', path) 36 | 37 | logger = Logger(env.dt) 38 | robot_index = 0 # which robot is used for logging 39 | joint_index = 1 # which joint is used for logging 40 | stop_state_log = 100 # number of steps before plotting states 41 | stop_rew_log = env.max_episode_length + 1 # number of steps before print average episode rewards 42 | camera_position = np.array(env_cfg.viewer.pos, dtype=np.float64) 43 | camera_vel = np.array([1., 1., 0.]) 44 | camera_direction = np.array(env_cfg.viewer.lookat) - np.array(env_cfg.viewer.pos) 45 | img_idx = 0 46 | 47 | for i in range(10*int(env.max_episode_length)): 48 | actions = torch.zeros((env_cfg.env.num_envs,env_cfg.env.num_actions)) 49 | obs, _, _, obs_hist, rews, dones, infos = env.step(actions.detach()) 50 | if RECORD_FRAMES: 51 | if i % 2: 52 | filename = os.path.join(LEGGED_GYM_ROOT_DIR, 'logs', train_cfg.runner.experiment_name, 'exported', 'frames', f"{img_idx}.png") 53 | env.gym.write_viewer_image_to_file(env.viewer, filename) 54 | img_idx += 1 55 | if MOVE_CAMERA: 56 | camera_position += camera_vel * env.dt 57 | env.set_camera(camera_position, camera_position + camera_direction) 58 | 59 | if i < stop_state_log: 60 | logger.log_states( 61 | { 62 | 'dof_pos_target': actions[robot_index, joint_index].item() * env.cfg.control.action_scale, 63 | 'dof_pos': env.dof_pos[robot_index, joint_index].item(), 64 | 'dof_vel': env.dof_vel[robot_index, joint_index].item(), 65 | 'dof_torque': env.torques[robot_index, joint_index].item(), 66 | 'command_x': env.commands[robot_index, 0].item(), 67 | 'command_y': env.commands[robot_index, 1].item(), 68 | 'command_yaw': env.commands[robot_index, 2].item(), 69 | 'base_vel_x': env.base_lin_vel[robot_index, 0].item(), 70 | 'base_vel_y': env.base_lin_vel[robot_index, 1].item(), 71 | 'base_vel_z': env.base_lin_vel[robot_index, 2].item(), 72 | 'base_vel_yaw': env.base_ang_vel[robot_index, 2].item(), 73 | 'contact_forces_z': env.contact_forces[robot_index, env.feet_indices, 2].cpu().numpy() 74 | } 75 | ) 76 | elif i==stop_state_log: 77 | logger.plot_states() 78 | if 0 < i < stop_rew_log: 79 | if infos["episode"]: 80 | num_episodes = torch.sum(env.reset_buf).item() 81 | if num_episodes>0: 82 | logger.log_rewards(infos["episode"], num_episodes) 83 | elif i==stop_rew_log: 84 | logger.print_rewards() 85 | 86 | if __name__ == '__main__': 87 | EXPORT_POLICY = True 88 | RECORD_FRAMES = False 89 | MOVE_CAMERA = False 90 | args = get_args() 91 | play(args) -------------------------------------------------------------------------------- /legged_gym/legged_gym/scripts/train.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | import numpy as np 32 | import os 33 | from datetime import datetime 34 | 35 | import isaacgym 36 | from legged_gym.envs import * 37 | from legged_gym.utils import get_args, task_registry 38 | import torch 39 | 40 | def train(args): 41 | env, env_cfg = task_registry.make_env(name=args.task, args=args) 42 | ppo_runner, train_cfg = task_registry.make_alg_runner(env=env, name=args.task, args=args) 43 | ppo_runner.learn(num_learning_iterations=train_cfg.runner.max_iterations, init_at_random_ep_len=True) 44 | 45 | if __name__ == '__main__': 46 | args = get_args() 47 | train(args) 48 | -------------------------------------------------------------------------------- /legged_gym/legged_gym/tests/test_env.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | import numpy as np 32 | import os 33 | from datetime import datetime 34 | 35 | import isaacgym 36 | from legged_gym.envs import * 37 | from legged_gym.utils import get_args, export_policy_as_jit, task_registry, Logger 38 | 39 | import torch 40 | 41 | 42 | def test_env(args): 43 | env_cfg, train_cfg = task_registry.get_cfgs(name=args.task) 44 | # override some parameters for testing 45 | env_cfg.env.num_envs = min(env_cfg.env.num_envs, 10) 46 | 47 | # prepare environment 48 | env, _ = task_registry.make_env(name=args.task, args=args, env_cfg=env_cfg) 49 | for i in range(int(10*env.max_episode_length)): 50 | actions = 0.*torch.ones(env.num_envs, env.num_actions, device=env.device) 51 | obs, _, rew, done, info = env.step(actions) 52 | print("Done") 53 | 54 | if __name__ == '__main__': 55 | args = get_args() 56 | test_env(args) 57 | -------------------------------------------------------------------------------- /legged_gym/legged_gym/utils/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | from .helpers import class_to_dict, get_load_path, get_args, export_policy_as_jit, set_seed, update_class_from_dict 32 | from .task_registry import task_registry 33 | from .logger import Logger 34 | from .math import * 35 | from .terrain import Terrain -------------------------------------------------------------------------------- /legged_gym/legged_gym/utils/math.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | import torch 32 | from torch import Tensor 33 | import numpy as np 34 | from isaacgym.torch_utils import quat_apply, normalize 35 | from typing import Tuple 36 | 37 | # @ torch.jit.script 38 | def quat_apply_yaw(quat, vec): 39 | quat_yaw = quat.clone().view(-1, 4) 40 | quat_yaw[:, :2] = 0. 41 | quat_yaw = normalize(quat_yaw) 42 | return quat_apply(quat_yaw, vec) 43 | 44 | # @ torch.jit.script 45 | def wrap_to_pi(angles): 46 | angles %= 2*np.pi 47 | angles -= 2*np.pi * (angles > np.pi) 48 | return angles 49 | 50 | # @ torch.jit.script 51 | def torch_rand_sqrt_float(lower, upper, shape, device): 52 | # type: (float, float, Tuple[int, int], str) -> Tensor 53 | r = 2*torch.rand(*shape, device=device) - 1 54 | r = torch.where(r<0., -torch.sqrt(-r), torch.sqrt(r)) 55 | r = (r + 1.) / 2. 56 | return (upper - lower) * r + lower 57 | 58 | 59 | def get_scale_shift(range): 60 | scale = 2. / (range[1] - range[0]) 61 | shift = (range[1] + range[0]) / 2. 62 | return scale, shift -------------------------------------------------------------------------------- /legged_gym/licenses/assets/ANYmal_b_license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2019 ANYbotics, https://www.anybotics.com 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, this 10 | list of conditions and the following disclaimer in the documentation and/or 11 | other materials provided with the distribution. 12 | 13 | 3. The name of ANYbotics and ANYmal may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 | POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /legged_gym/licenses/assets/ANYmal_c_license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2020, ANYbotics AG. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions 5 | are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the 13 | distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived 17 | from this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /legged_gym/licenses/assets/cassie_license.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Jenna Reher, jreher@caltech.edu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /legged_gym/licenses/dependencies/matplotlib_license.txt: -------------------------------------------------------------------------------- 1 | 1. This LICENSE AGREEMENT is between the Matplotlib Development Team ("MDT"), and the Individual or Organization ("Licensee") accessing and otherwise using matplotlib software in source or binary form and its associated documentation. 2 | 3 | 2. Subject to the terms and conditions of this License Agreement, MDT hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use matplotlib 3.4.3 alone or in any derivative version, provided, however, that MDT's License Agreement and MDT's notice of copyright, i.e., "Copyright (c) 2012-2013 Matplotlib Development Team; All Rights Reserved" are retained in matplotlib 3.4.3 alone or in any derivative version prepared by Licensee. 4 | 5 | 3. In the event Licensee prepares a derivative work that is based on or incorporates matplotlib 3.4.3 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to matplotlib 3.4.3. 6 | 7 | 4. MDT is making matplotlib 3.4.3 available to Licensee on an "AS IS" basis. MDT MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, MDT MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF MATPLOTLIB 3.4.3 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 8 | 9 | 5. MDT SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF MATPLOTLIB 3.4.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING MATPLOTLIB 3.4.3, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 10 | 11 | 6. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 12 | 13 | 7. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between MDT and Licensee. This License Agreement does not grant permission to use MDT trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party. 14 | 15 | 8. By copying, installing or otherwise using matplotlib 3.4.3, Licensee agrees to be bound by the terms and conditions of this License Agreement. -------------------------------------------------------------------------------- /legged_gym/resources/actuator_nets/anydrive_v3_lstm.pt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/actuator_nets/anydrive_v3_lstm.pt -------------------------------------------------------------------------------- /legged_gym/resources/robots/a1/meshes/trunk_A1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/a1/meshes/trunk_A1.png -------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_b/ANYmal_b_license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2019 ANYbotics, https://www.anybotics.com 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, this 10 | list of conditions and the following disclaimer in the documentation and/or 11 | other materials provided with the distribution. 12 | 13 | 3. The name of ANYbotics and ANYmal may not be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 | POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_b/meshes/base_uv_texture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/anymal_b/meshes/base_uv_texture.jpg -------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_b/meshes/carbon_uv_texture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/anymal_b/meshes/carbon_uv_texture.jpg -------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_c/ANYmal_c_license.txt: -------------------------------------------------------------------------------- 1 | Copyright 2020, ANYbotics AG. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions 5 | are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the 13 | distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived 17 | from this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_c/meshes/base.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/anymal_c/meshes/base.jpg -------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_c/meshes/battery.dae: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Blender User 6 | Blender 2.81.16 commit date:2019-11-20, commit time:14:27, hash:26bd5ebd42e3 7 | 8 | 2020-01-07T14:47:32 9 | 2020-01-07T14:47:32 10 | 11 | Z_UP 12 | 13 | 14 | 15 | 16 | 17 | 18 | battery 19 | 20 | 21 | 22 | 23 | battery-surface 24 | 25 | 26 | 27 | 28 | 29 | 0 0 0 1 30 | 31 | 32 | 33 | 34 | 35 | 1.45 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | battery.jpg 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -0.225881 -0.06249898 -0.03684729 -0.225881 -0.06249898 0.03725165 -0.225881 0.06249898 -0.03684729 -0.225881 0.06249898 0.03725165 0.232213 -0.06249898 -0.03684729 0.232213 -0.06249898 0.03725165 0.232213 0.06249898 -0.03684729 0.232213 0.06249898 0.03725165 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -1 0 0 0 1 0 1 0 0 0 -1 0 0 0 -1 0 0 1 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 0.8431081 0.2728654 1 0 1 0.2728654 0.6862162 1 0.8431079 0 0.8431081 1 0.8431081 0.5457308 1 0.2728654 1 0.5457308 0.6862159 0 0.5293241 1 0.5293239 0 0.264662 0 0.5293239 0.9999999 0.2646622 0.9999999 0.264662 0.9999999 0 0 0.2646618 0 0.8431081 0.2728654 0.8431081 0 1 0 0.6862162 1 0.6862161 0 0.8431079 0 0.8431081 0.5457308 0.8431081 0.2728654 1 0.2728654 0.6862159 0 0.6862161 1 0.5293241 1 0.264662 0 0.5293238 0 0.5293239 0.9999999 0.264662 0.9999999 1.73529e-7 0.9999999 0 0 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 |

1 0 0 2 0 1 0 0 2 3 1 3 6 1 4 2 1 5 7 2 6 4 2 7 6 2 8 5 3 9 0 3 10 4 3 11 6 4 12 0 4 13 2 4 14 3 5 15 5 5 16 7 5 17 1 0 18 3 0 19 2 0 20 3 1 21 7 1 22 6 1 23 7 2 24 5 2 25 4 2 26 5 3 27 1 3 28 0 3 29 6 4 30 4 4 31 0 4 32 3 5 33 1 5 34 5 5 35

92 |
93 |
94 |
95 |
96 | 97 | 98 | 99 | 1 0 0 0 0 1 0 0 0 0 1 -0.03329167 0 0 0 1 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
-------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_c/meshes/battery.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/anymal_c/meshes/battery.jpg -------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_c/meshes/bottom_shell.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/anymal_c/meshes/bottom_shell.jpg -------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_c/meshes/depth_camera.dae: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Blender User 6 | Blender 2.82.7 commit date:2020-02-12, commit time:16:20, hash:77d23b0bd76f 7 | 8 | 2020-02-20T10:55:16 9 | 2020-02-20T10:55:16 10 | 11 | Z_UP 12 | 13 | 14 | 15 | 16 | 17 | 18 | depth_camera 19 | 20 | 21 | 22 | 23 | depth_camera-surface 24 | 25 | 26 | 27 | 28 | 29 | 0 0 0 1 30 | 31 | 32 | 33 | 34 | 35 | 1.45 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | depth_camera.jpg 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 0 -0.04699999 -0.01968461 0 -0.04699999 0.01951932 0 0.04699999 -0.01968461 0 0.04699999 0.01951932 0.03039997 -0.04699999 -0.01968461 0.03039997 -0.04699999 0.01951932 0.03039997 0.04699999 -0.01968461 0.03039997 0.04699999 0.01951932 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -1 0 0 1 0 0 0 0 1 0 -1 0 0 1 0 0 0 -1 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 0.2816218 0.7056847 0.5632433 0 0.5632433 0.7056847 1.60564e-7 0.7056847 0.2816215 0 0.2816217 0.7056847 0.7816217 0.7056846 1 0 1 0.7056846 0.5632433 0.7056847 0.344865 1 0.344865 0.7056847 0.7816216 0.7056847 0.5632434 1 0.5632433 0.7056847 0.7816217 0 0.5632433 0.7056846 0.5632434 0 0.2816218 0.7056847 0.2816217 0 0.5632433 0 1.60564e-7 0.7056847 0 0 0.2816215 0 0.7816217 0.7056846 0.7816217 0 1 0 0.5632433 0.7056847 0.5632433 1 0.344865 1 0.7816216 0.7056847 0.7816218 1 0.5632434 1 0.7816217 0 0.7816216 0.7056846 0.5632433 0.7056846 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 |

1 0 0 2 0 1 0 0 2 7 1 3 4 1 4 6 1 5 3 2 6 5 2 7 7 2 8 1 3 9 4 3 10 5 3 11 7 4 12 2 4 13 3 4 14 6 5 15 0 5 16 2 5 17 1 0 18 3 0 19 2 0 20 7 1 21 5 1 22 4 1 23 3 2 24 1 2 25 5 2 26 1 3 27 0 3 28 4 3 29 7 4 30 6 4 31 2 4 32 6 5 33 4 5 34 0 5 35

92 |
93 |
94 |
95 |
96 | 97 | 98 | 99 | 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
-------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_c/meshes/depth_camera.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/anymal_c/meshes/depth_camera.jpg -------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_c/meshes/drive.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/anymal_c/meshes/drive.jpg -------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_c/meshes/face.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/anymal_c/meshes/face.jpg -------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_c/meshes/foot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/anymal_c/meshes/foot.jpg -------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_c/meshes/handle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/anymal_c/meshes/handle.jpg -------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_c/meshes/hatch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/anymal_c/meshes/hatch.jpg -------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_c/meshes/hip.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/anymal_c/meshes/hip.jpg -------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_c/meshes/lidar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/anymal_c/meshes/lidar.jpg -------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_c/meshes/lidar_cage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/anymal_c/meshes/lidar_cage.jpg -------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_c/meshes/remote.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/anymal_c/meshes/remote.jpg -------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_c/meshes/shank.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/anymal_c/meshes/shank.jpg -------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_c/meshes/thigh.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/anymal_c/meshes/thigh.jpg -------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_c/meshes/top_shell.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/anymal_c/meshes/top_shell.jpg -------------------------------------------------------------------------------- /legged_gym/resources/robots/anymal_c/meshes/wide_angle_camera.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/anymal_c/meshes/wide_angle_camera.jpg -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/cassie_license.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Jenna Reher, jreher@caltech.edu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/meshes/abduction.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/cassie/meshes/abduction.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/meshes/abduction_mirror.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/cassie/meshes/abduction_mirror.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/meshes/achilles-rod.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/cassie/meshes/achilles-rod.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/meshes/hip.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/cassie/meshes/hip.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/meshes/hip_mirror.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/cassie/meshes/hip_mirror.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/meshes/knee-output.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/cassie/meshes/knee-output.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/meshes/knee-output_mirror.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/cassie/meshes/knee-output_mirror.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/meshes/pelvis.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/cassie/meshes/pelvis.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/meshes/plantar-rod.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/cassie/meshes/plantar-rod.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/meshes/shin-bone.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/cassie/meshes/shin-bone.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/meshes/shin-bone_mirror.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/cassie/meshes/shin-bone_mirror.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/meshes/tarsus.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/cassie/meshes/tarsus.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/meshes/tarsus_mirror.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/cassie/meshes/tarsus_mirror.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/meshes/thigh.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/cassie/meshes/thigh.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/meshes/thigh_mirror.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/cassie/meshes/thigh_mirror.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/meshes/toe-output-crank.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/cassie/meshes/toe-output-crank.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/meshes/toe.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/cassie/meshes/toe.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/meshes/toe_mirror.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/cassie/meshes/toe_mirror.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/meshes/torso.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/cassie/meshes/torso.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/meshes/yaw.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/cassie/meshes/yaw.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/cassie/meshes/yaw_mirror.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/cassie/meshes/yaw_mirror.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/go1/meshes/calf.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/go1/meshes/calf.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/go1/meshes/hip.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/go1/meshes/hip.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/go1/meshes/thigh.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/go1/meshes/thigh.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/go1/meshes/thigh_mirror.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/go1/meshes/thigh_mirror.stl -------------------------------------------------------------------------------- /legged_gym/resources/robots/go1/meshes/trunk.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/resources/robots/go1/meshes/trunk.stl -------------------------------------------------------------------------------- /legged_gym/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import find_packages 2 | from distutils.core import setup 3 | 4 | setup( 5 | name='legged_gym', 6 | version='1.0.0', 7 | author='Nikita Rudin', 8 | license="BSD-3-Clause", 9 | packages=find_packages(), 10 | author_email='rudinn@ethz.ch', 11 | description='Isaac Gym environments for Legged Robots', 12 | install_requires=['isaacgym', 13 | 'rsl-rl', 14 | 'matplotlib'] 15 | ) -------------------------------------------------------------------------------- /legged_gym/train_cfg.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Manaro-Alpha/DreamWaQ/5c6eb59e01890c3b511d6f893b3b343b489bd322/legged_gym/train_cfg.pkl -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # DreamWaQ 2 | 3 | ## Description 4 | This repo contains implementation of the paper [Learning Robust Quadrupedal Locomotion With Implicit Terrain Imagination via Deep Reinforcement Learning](https://arxiv.org/abs/2301.10602) 5 | 6 | ## Table of Contents 7 | - [Installation](#installation) 8 | - [Usage](#usage) 9 | - [Configuration](#configuration) 10 | 11 | ## Installation 12 | This repo requires the following packages: 13 | - [Isaac Gym](https://developer.nvidia.com/isaac-gym) 14 | - Legged Gym 15 | - RSL-RL 16 | 17 | To install Isaac Gym, go to the link and follow the instructions on the page. 18 | 19 | 1. clone this repo 20 | 21 | 2. 22 | ```bash 23 | cd rsl_rl-1.0.2 24 | pip install -e . 25 | cd .. 26 | ``` 27 | 3. 28 | ```bash 29 | cd legged_gym 30 | pip install -e . 31 | cd .. 32 | ``` 33 | 34 | ## Usage 35 | To train your robot run 36 | ```bash 37 | python3 legged_gym/scripts/train.py --task=[robot name] 38 | ``` 39 | 40 | To evaluate the trained policy run 41 | ```bash 42 | python3 legged_gym/scripts/play.py --task=[robot name] 43 | ``` 44 | Go1: 45 | 46 | ![Go1](DwaQ_stairs.gif) 47 | 48 | ## Configuration 49 | Requires python 3.8 and numpy version<=1.24. 50 | -------------------------------------------------------------------------------- /rsl_rl-1.0.2/.gitignore: -------------------------------------------------------------------------------- 1 | # IDEs 2 | .idea 3 | 4 | # builds 5 | *.egg-info 6 | 7 | # cache 8 | __pycache__ 9 | .pytest_cache 10 | 11 | # vs code 12 | .vscode -------------------------------------------------------------------------------- /rsl_rl-1.0.2/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021, ETH Zurich, Nikita Rudin 2 | Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors 16 | may be used to endorse or promote products derived from this software without 17 | specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 23 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | See licenses/dependencies for license information of dependencies of this package. -------------------------------------------------------------------------------- /rsl_rl-1.0.2/README.md: -------------------------------------------------------------------------------- 1 | # RSL RL 2 | Fast and simple implementation of RL algorithms, designed to run fully on GPU. 3 | This code is an evolution of `rl-pytorch` provided with NVIDIA's Isaac GYM. 4 | 5 | Only PPO is implemented for now. More algorithms will be added later. 6 | Contributions are welcome. 7 | 8 | ## Setup 9 | 10 | ``` 11 | git clone https://github.com/leggedrobotics/rsl_rl 12 | cd rsl_rl 13 | pip install -e . 14 | ``` 15 | 16 | ### Useful Links ### 17 | Example use case: https://github.com/leggedrobotics/legged_gym 18 | Project website: https://leggedrobotics.github.io/legged_gym/ 19 | Paper: https://arxiv.org/abs/2109.11978 20 | 21 | **Maintainer**: Nikita Rudin 22 | **Affiliation**: Robotic Systems Lab, ETH Zurich & NVIDIA 23 | **Contact**: rudinn@ethz.ch 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /rsl_rl-1.0.2/licenses/dependencies/numpy_license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2005-2021, NumPy Developers. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of the NumPy Developers nor the names of any 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /rsl_rl-1.0.2/licenses/dependencies/torch_license.txt: -------------------------------------------------------------------------------- 1 | From PyTorch: 2 | 3 | Copyright (c) 2016- Facebook, Inc (Adam Paszke) 4 | Copyright (c) 2014- Facebook, Inc (Soumith Chintala) 5 | Copyright (c) 2011-2014 Idiap Research Institute (Ronan Collobert) 6 | Copyright (c) 2012-2014 Deepmind Technologies (Koray Kavukcuoglu) 7 | Copyright (c) 2011-2012 NEC Laboratories America (Koray Kavukcuoglu) 8 | Copyright (c) 2011-2013 NYU (Clement Farabet) 9 | Copyright (c) 2006-2010 NEC Laboratories America (Ronan Collobert, Leon Bottou, Iain Melvin, Jason Weston) 10 | Copyright (c) 2006 Idiap Research Institute (Samy Bengio) 11 | Copyright (c) 2001-2004 Idiap Research Institute (Ronan Collobert, Samy Bengio, Johnny Mariethoz) 12 | 13 | From Caffe2: 14 | 15 | Copyright (c) 2016-present, Facebook Inc. All rights reserved. 16 | 17 | All contributions by Facebook: 18 | Copyright (c) 2016 Facebook Inc. 19 | 20 | All contributions by Google: 21 | Copyright (c) 2015 Google Inc. 22 | All rights reserved. 23 | 24 | All contributions by Yangqing Jia: 25 | Copyright (c) 2015 Yangqing Jia 26 | All rights reserved. 27 | 28 | All contributions by Kakao Brain: 29 | Copyright 2019-2020 Kakao Brain 30 | 31 | All contributions from Caffe: 32 | Copyright(c) 2013, 2014, 2015, the respective contributors 33 | All rights reserved. 34 | 35 | All other contributions: 36 | Copyright(c) 2015, 2016 the respective contributors 37 | All rights reserved. 38 | 39 | Caffe2 uses a copyright model similar to Caffe: each contributor holds 40 | copyright over their contributions to Caffe2. The project versioning records 41 | all such contribution and copyright details. If a contributor wants to further 42 | mark their specific copyright on a particular contribution, they should 43 | indicate their copyright solely in the commit message of the change when it is 44 | committed. 45 | 46 | All rights reserved. 47 | 48 | Redistribution and use in source and binary forms, with or without 49 | modification, are permitted provided that the following conditions are met: 50 | 51 | 1. Redistributions of source code must retain the above copyright 52 | notice, this list of conditions and the following disclaimer. 53 | 54 | 2. Redistributions in binary form must reproduce the above copyright 55 | notice, this list of conditions and the following disclaimer in the 56 | documentation and/or other materials provided with the distribution. 57 | 58 | 3. Neither the names of Facebook, Deepmind Technologies, NYU, NEC Laboratories America 59 | and IDIAP Research Institute nor the names of its contributors may be 60 | used to endorse or promote products derived from this software without 61 | specific prior written permission. 62 | 63 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 64 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 65 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 66 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 67 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 68 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 69 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 70 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 71 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 72 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 73 | POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /rsl_rl-1.0.2/rsl_rl/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin -------------------------------------------------------------------------------- /rsl_rl-1.0.2/rsl_rl/algorithms/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | from .ppo import PPO -------------------------------------------------------------------------------- /rsl_rl-1.0.2/rsl_rl/env/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | from .vec_env import VecEnv -------------------------------------------------------------------------------- /rsl_rl-1.0.2/rsl_rl/env/vec_env.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | from abc import ABC, abstractmethod 32 | import torch 33 | from typing import Tuple, Union 34 | 35 | # minimal interface of the environment 36 | class VecEnv(ABC): 37 | num_envs: int 38 | num_obs: int 39 | num_privileged_obs: int 40 | num_actions: int 41 | max_episode_length: int 42 | privileged_obs_buf: torch.Tensor 43 | obs_buf: torch.Tensor 44 | rew_buf: torch.Tensor 45 | reset_buf: torch.Tensor 46 | episode_length_buf: torch.Tensor # current episode duration 47 | extras: dict 48 | device: torch.device 49 | @abstractmethod 50 | def step(self, actions: torch.Tensor) -> Tuple[torch.Tensor, Union[torch.Tensor, None], torch.Tensor, torch.Tensor, dict]: 51 | pass 52 | @abstractmethod 53 | def reset(self, env_ids: Union[list, torch.Tensor]): 54 | pass 55 | @abstractmethod 56 | def get_observations(self) -> torch.Tensor: 57 | pass 58 | @abstractmethod 59 | def get_privileged_observations(self) -> Union[torch.Tensor, None]: 60 | pass -------------------------------------------------------------------------------- /rsl_rl-1.0.2/rsl_rl/modules/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | from .actor_critic import ActorCritic 32 | from .actor_critic_recurrent import ActorCriticRecurrent 33 | from .actor_critic_DWAQ import ActorCritic_DWAQ -------------------------------------------------------------------------------- /rsl_rl-1.0.2/rsl_rl/modules/actor_critic.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | import numpy as np 32 | 33 | import torch 34 | import torch.nn as nn 35 | from torch.distributions import Normal 36 | from torch.nn.modules import rnn 37 | 38 | class ActorCritic(nn.Module): 39 | is_recurrent = False 40 | def __init__(self, num_actor_obs, 41 | num_critic_obs, 42 | num_actions, 43 | actor_hidden_dims=[256, 256, 256], 44 | critic_hidden_dims=[256, 256, 256], 45 | activation='elu', 46 | init_noise_std=1.0, 47 | **kwargs): 48 | if kwargs: 49 | print("ActorCritic.__init__ got unexpected arguments, which will be ignored: " + str([key for key in kwargs.keys()])) 50 | super(ActorCritic, self).__init__() 51 | 52 | activation = get_activation(activation) 53 | 54 | mlp_input_dim_a = num_actor_obs 55 | mlp_input_dim_c = num_critic_obs 56 | 57 | # Policy 58 | actor_layers = [] 59 | actor_layers.append(nn.Linear(mlp_input_dim_a, actor_hidden_dims[0])) 60 | actor_layers.append(activation) 61 | for l in range(len(actor_hidden_dims)): 62 | if l == len(actor_hidden_dims) - 1: 63 | actor_layers.append(nn.Linear(actor_hidden_dims[l], num_actions)) 64 | else: 65 | actor_layers.append(nn.Linear(actor_hidden_dims[l], actor_hidden_dims[l + 1])) 66 | actor_layers.append(activation) 67 | self.actor = nn.Sequential(*actor_layers) 68 | 69 | # Value function 70 | critic_layers = [] 71 | critic_layers.append(nn.Linear(mlp_input_dim_c, critic_hidden_dims[0])) 72 | critic_layers.append(activation) 73 | for l in range(len(critic_hidden_dims)): 74 | if l == len(critic_hidden_dims) - 1: 75 | critic_layers.append(nn.Linear(critic_hidden_dims[l], 1)) 76 | else: 77 | critic_layers.append(nn.Linear(critic_hidden_dims[l], critic_hidden_dims[l + 1])) 78 | critic_layers.append(activation) 79 | self.critic = nn.Sequential(*critic_layers) 80 | 81 | print(f"Actor MLP: {self.actor}") 82 | print(f"Critic MLP: {self.critic}") 83 | 84 | # Action noise 85 | self.std = nn.Parameter(init_noise_std * torch.ones(num_actions)) 86 | self.distribution = None 87 | # disable args validation for speedup 88 | Normal.set_default_validate_args = False 89 | 90 | # seems that we get better performance without init 91 | # self.init_memory_weights(self.memory_a, 0.001, 0.) 92 | # self.init_memory_weights(self.memory_c, 0.001, 0.) 93 | 94 | @staticmethod 95 | # not used at the moment 96 | def init_weights(sequential, scales): 97 | [torch.nn.init.orthogonal_(module.weight, gain=scales[idx]) for idx, module in 98 | enumerate(mod for mod in sequential if isinstance(mod, nn.Linear))] 99 | 100 | 101 | def reset(self, dones=None): 102 | pass 103 | 104 | def forward(self): 105 | raise NotImplementedError 106 | 107 | @property 108 | def action_mean(self): 109 | return self.distribution.mean 110 | 111 | @property 112 | def action_std(self): 113 | return self.distribution.stddev 114 | 115 | @property 116 | def entropy(self): 117 | return self.distribution.entropy().sum(dim=-1) 118 | 119 | def update_distribution(self, observations): 120 | mean = self.actor(observations) 121 | self.distribution = Normal(mean, mean*0. + self.std) 122 | 123 | def act(self, observations, **kwargs): 124 | self.update_distribution(observations) 125 | return self.distribution.sample() 126 | 127 | def get_actions_log_prob(self, actions): 128 | return self.distribution.log_prob(actions).sum(dim=-1) 129 | 130 | def act_inference(self, observations): 131 | actions_mean = self.actor(observations) 132 | return actions_mean 133 | 134 | def evaluate(self, critic_observations, **kwargs): 135 | value = self.critic(critic_observations) 136 | return value 137 | 138 | def get_activation(act_name): 139 | if act_name == "elu": 140 | return nn.ELU() 141 | elif act_name == "selu": 142 | return nn.SELU() 143 | elif act_name == "relu": 144 | return nn.ReLU() 145 | elif act_name == "crelu": 146 | return nn.ReLU() 147 | elif act_name == "lrelu": 148 | return nn.LeakyReLU() 149 | elif act_name == "tanh": 150 | return nn.Tanh() 151 | elif act_name == "sigmoid": 152 | return nn.Sigmoid() 153 | else: 154 | print("invalid activation function!") 155 | return None 156 | -------------------------------------------------------------------------------- /rsl_rl-1.0.2/rsl_rl/modules/actor_critic_DWAQ.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import torch 4 | import torch.nn as nn 5 | from torch.distributions import Normal 6 | 7 | class ActorCritic_DWAQ(nn.Module): 8 | def __init__(self, num_actor_obs, num_critic_obs, num_actions, cenet_in_dim, cenet_out_dim, activation="elu", init_noise_std=1.0,): 9 | super().__init__() 10 | 11 | self.activation = get_activation(activation) 12 | actor_input_dim = num_actor_obs 13 | critic_input_dim = num_critic_obs 14 | 15 | self.actor = nn.Sequential( 16 | nn.Linear(actor_input_dim,512), 17 | self.activation, 18 | nn.Linear(512,256), 19 | self.activation, 20 | nn.Linear(256,128), 21 | self.activation, 22 | nn.Linear(128,num_actions) 23 | ) 24 | 25 | self.critic = nn.Sequential( 26 | nn.Linear(critic_input_dim,512), 27 | self.activation, 28 | nn.Linear(512,256), 29 | self.activation, 30 | nn.Linear(256,128), 31 | self.activation, 32 | nn.Linear(128,1) 33 | ) 34 | 35 | self.encoder = nn.Sequential( 36 | nn.Linear(cenet_in_dim,128), 37 | self.activation, 38 | nn.Linear(128,64), 39 | self.activation, 40 | ) 41 | self.encode_mean_latent = nn.Linear(64,cenet_out_dim-3) 42 | self.encode_logvar_latent = nn.Linear(64,cenet_out_dim-3) 43 | self.encode_mean_vel = nn.Linear(64,3) 44 | self.encode_logvar_vel = nn.Linear(64,3) 45 | 46 | self.decoder = nn.Sequential( 47 | nn.Linear(cenet_out_dim,64), 48 | self.activation, 49 | nn.Linear(64,128), 50 | self.activation, 51 | nn.Linear(128,45) 52 | ) 53 | 54 | self.std = nn.Parameter(init_noise_std * torch.ones(num_actions)) 55 | self.distribution = None 56 | # disable args validation for speedup 57 | Normal.set_default_validate_args = False 58 | 59 | # seems that we get better performance without init 60 | # self.init_memory_weights(self.memory_a, 0.001, 0.) 61 | # self.init_memory_weights(self.memory_c, 0.001, 0.) 62 | 63 | @staticmethod 64 | # not used at the moment 65 | def init_weights(sequential, scales): 66 | [ 67 | torch.nn.init.orthogonal_(module.weight, gain=scales[idx]) 68 | for idx, module in enumerate(mod for mod in sequential if isinstance(mod, nn.Linear)) 69 | ] 70 | 71 | def reset(self, dones=None): 72 | pass 73 | 74 | def forward(self): 75 | raise NotImplementedError 76 | 77 | def reparameterise(self,mean,logvar): 78 | var = torch.exp(logvar*0.5) 79 | code_temp = torch.randn_like(var) 80 | code = mean + var*code_temp 81 | return code 82 | 83 | def cenet_forward(self,obs_history): 84 | distribution = self.encoder(obs_history) 85 | mean_latent = self.encode_mean_latent(distribution) 86 | logvar_latent = self.encode_logvar_latent(distribution) 87 | # var = torch.exp(logvar_latent*0.5) 88 | # code_temp = torch.randn_like(var) 89 | # code = mean_latent + var*code_temp 90 | # print("latent : ",code[0]) 91 | mean_vel = self.encode_mean_vel(distribution) 92 | logvar_vel = self.encode_mean_vel(distribution) 93 | code_latent = self.reparameterise(mean_latent,logvar_latent) 94 | code_vel = self.reparameterise(mean_vel,logvar_vel) 95 | code = torch.cat((code_vel,code_latent),dim=-1) 96 | decode = self.decoder(code) 97 | return code,code_vel,decode,mean_vel,logvar_vel,mean_latent,logvar_latent 98 | 99 | @property 100 | def action_mean(self): 101 | return self.distribution.mean 102 | 103 | @property 104 | def action_std(self): 105 | return self.distribution.stddev 106 | 107 | @property 108 | def entropy(self): 109 | return self.distribution.entropy().sum(dim=-1) 110 | 111 | def update_distribution(self, observations): 112 | mean = self.actor(observations) 113 | self.distribution = Normal(mean, mean * 0.0 + self.std) 114 | 115 | def act(self, observations, obs_history, **kwargs): 116 | code,_,decode,_,_,_,_ = self.cenet_forward(obs_history) 117 | observations = torch.cat((code,observations),dim=-1) 118 | self.update_distribution(observations) 119 | return self.distribution.sample() 120 | 121 | def get_actions_log_prob(self, actions): 122 | return self.distribution.log_prob(actions).sum(dim=-1) 123 | 124 | def act_inference(self, observations,obs_history): 125 | code,_,decode,_,_,_,_ = self.cenet_forward(obs_history) 126 | observations = torch.cat((code,observations),dim=-1) 127 | actions_mean = self.actor(observations) 128 | return actions_mean 129 | 130 | def evaluate(self, critic_observations, **kwargs): 131 | value = self.critic(critic_observations) 132 | return value 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | def get_activation(act_name): 149 | if act_name == "elu": 150 | return nn.ELU() 151 | elif act_name == "selu": 152 | return nn.SELU() 153 | elif act_name == "relu": 154 | return nn.ReLU() 155 | elif act_name == "crelu": 156 | return nn.CReLU() 157 | elif act_name == "lrelu": 158 | return nn.LeakyReLU() 159 | elif act_name == "tanh": 160 | return nn.Tanh() 161 | elif act_name == "sigmoid": 162 | return nn.Sigmoid() 163 | else: 164 | print("invalid activation function!") 165 | return None 166 | -------------------------------------------------------------------------------- /rsl_rl-1.0.2/rsl_rl/modules/actor_critic_recurrent.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | import numpy as np 32 | 33 | import torch 34 | import torch.nn as nn 35 | from torch.distributions import Normal 36 | from torch.nn.modules import rnn 37 | from .actor_critic import ActorCritic, get_activation 38 | from rsl_rl.utils import unpad_trajectories 39 | 40 | class ActorCriticRecurrent(ActorCritic): 41 | is_recurrent = True 42 | def __init__(self, num_actor_obs, 43 | num_critic_obs, 44 | num_actions, 45 | actor_hidden_dims=[256, 256, 256], 46 | critic_hidden_dims=[256, 256, 256], 47 | activation='elu', 48 | rnn_type='lstm', 49 | rnn_hidden_size=256, 50 | rnn_num_layers=1, 51 | init_noise_std=1.0, 52 | **kwargs): 53 | if kwargs: 54 | print("ActorCriticRecurrent.__init__ got unexpected arguments, which will be ignored: " + str(kwargs.keys()),) 55 | 56 | super().__init__(num_actor_obs=rnn_hidden_size, 57 | num_critic_obs=rnn_hidden_size, 58 | num_actions=num_actions, 59 | actor_hidden_dims=actor_hidden_dims, 60 | critic_hidden_dims=critic_hidden_dims, 61 | activation=activation, 62 | init_noise_std=init_noise_std) 63 | 64 | activation = get_activation(activation) 65 | 66 | self.memory_a = Memory(num_actor_obs, type=rnn_type, num_layers=rnn_num_layers, hidden_size=rnn_hidden_size) 67 | self.memory_c = Memory(num_critic_obs, type=rnn_type, num_layers=rnn_num_layers, hidden_size=rnn_hidden_size) 68 | 69 | print(f"Actor RNN: {self.memory_a}") 70 | print(f"Critic RNN: {self.memory_c}") 71 | 72 | def reset(self, dones=None): 73 | self.memory_a.reset(dones) 74 | self.memory_c.reset(dones) 75 | 76 | def act(self, observations, masks=None, hidden_states=None): 77 | input_a = self.memory_a(observations, masks, hidden_states) 78 | return super().act(input_a.squeeze(0)) 79 | 80 | def act_inference(self, observations): 81 | input_a = self.memory_a(observations) 82 | return super().act_inference(input_a.squeeze(0)) 83 | 84 | def evaluate(self, critic_observations, masks=None, hidden_states=None): 85 | input_c = self.memory_c(critic_observations, masks, hidden_states) 86 | return super().evaluate(input_c.squeeze(0)) 87 | 88 | def get_hidden_states(self): 89 | return self.memory_a.hidden_states, self.memory_c.hidden_states 90 | 91 | 92 | class Memory(torch.nn.Module): 93 | def __init__(self, input_size, type='lstm', num_layers=1, hidden_size=256): 94 | super().__init__() 95 | # RNN 96 | rnn_cls = nn.GRU if type.lower() == 'gru' else nn.LSTM 97 | self.rnn = rnn_cls(input_size=input_size, hidden_size=hidden_size, num_layers=num_layers) 98 | self.hidden_states = None 99 | 100 | def forward(self, input, masks=None, hidden_states=None): 101 | batch_mode = masks is not None 102 | if batch_mode: 103 | # batch mode (policy update): need saved hidden states 104 | if hidden_states is None: 105 | raise ValueError("Hidden states not passed to memory module during policy update") 106 | out, _ = self.rnn(input, hidden_states) 107 | out = unpad_trajectories(out, masks) 108 | else: 109 | # inference mode (collection): use hidden states of last step 110 | out, self.hidden_states = self.rnn(input.unsqueeze(0), self.hidden_states) 111 | return out 112 | 113 | def reset(self, dones=None): 114 | # When the RNN is an LSTM, self.hidden_states_a is a list with hidden_state and cell_state 115 | for hidden_state in self.hidden_states: 116 | hidden_state[..., dones, :] = 0.0 -------------------------------------------------------------------------------- /rsl_rl-1.0.2/rsl_rl/runners/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | from .on_policy_runner import OnPolicyRunner -------------------------------------------------------------------------------- /rsl_rl-1.0.2/rsl_rl/storage/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2021 ETH Zurich, NVIDIA CORPORATION 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | from .rollout_storage import RolloutStorage -------------------------------------------------------------------------------- /rsl_rl-1.0.2/rsl_rl/utils/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | from .utils import split_and_pad_trajectories, unpad_trajectories -------------------------------------------------------------------------------- /rsl_rl-1.0.2/rsl_rl/utils/utils.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, this 8 | # list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Copyright (c) 2021 ETH Zurich, Nikita Rudin 30 | 31 | import torch 32 | 33 | def split_and_pad_trajectories(tensor, dones): 34 | """ Splits trajectories at done indices. Then concatenates them and padds with zeros up to the length og the longest trajectory. 35 | Returns masks corresponding to valid parts of the trajectories 36 | Example: 37 | Input: [ [a1, a2, a3, a4 | a5, a6], 38 | [b1, b2 | b3, b4, b5 | b6] 39 | ] 40 | 41 | Output:[ [a1, a2, a3, a4], | [ [True, True, True, True], 42 | [a5, a6, 0, 0], | [True, True, False, False], 43 | [b1, b2, 0, 0], | [True, True, False, False], 44 | [b3, b4, b5, 0], | [True, True, True, False], 45 | [b6, 0, 0, 0] | [True, False, False, False], 46 | ] | ] 47 | 48 | Assumes that the inputy has the following dimension order: [time, number of envs, aditional dimensions] 49 | """ 50 | dones = dones.clone() 51 | dones[-1] = 1 52 | # Permute the buffers to have order (num_envs, num_transitions_per_env, ...), for correct reshaping 53 | flat_dones = dones.transpose(1, 0).reshape(-1, 1) 54 | 55 | # Get length of trajectory by counting the number of successive not done elements 56 | done_indices = torch.cat((flat_dones.new_tensor([-1], dtype=torch.int64), flat_dones.nonzero()[:, 0])) 57 | trajectory_lengths = done_indices[1:] - done_indices[:-1] 58 | trajectory_lengths_list = trajectory_lengths.tolist() 59 | # Extract the individual trajectories 60 | trajectories = torch.split(tensor.transpose(1, 0).flatten(0, 1),trajectory_lengths_list) 61 | padded_trajectories = torch.nn.utils.rnn.pad_sequence(trajectories) 62 | 63 | 64 | trajectory_masks = trajectory_lengths > torch.arange(0, tensor.shape[0], device=tensor.device).unsqueeze(1) 65 | return padded_trajectories, trajectory_masks 66 | 67 | def unpad_trajectories(trajectories, masks): 68 | """ Does the inverse operation of split_and_pad_trajectories() 69 | """ 70 | # Need to transpose before and after the masking to have proper reshaping 71 | return trajectories.transpose(1, 0)[masks.transpose(1, 0)].view(-1, trajectories.shape[0], trajectories.shape[-1]).transpose(1, 0) -------------------------------------------------------------------------------- /rsl_rl-1.0.2/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup(name='rsl_rl', 4 | version='1.0.2', 5 | author='Nikita Rudin', 6 | author_email='rudinn@ethz.ch', 7 | license="BSD-3-Clause", 8 | packages=find_packages(), 9 | description='Fast and simple RL algorithms implemented in pytorch', 10 | python_requires='>=3.6', 11 | install_requires=[ 12 | "torch>=1.4.0", 13 | "torchvision>=0.5.0", 14 | "numpy>=1.16.4" 15 | ], 16 | ) 17 | --------------------------------------------------------------------------------