{"id":19855138,"url":"https://github.com/leggedrobotics/terra","last_synced_at":"2025-10-03T21:33:29.593Z","repository":{"id":228911864,"uuid":"621332621","full_name":"leggedrobotics/terra","owner":"leggedrobotics","description":"A grid world environment for high-level earthworks planning in JAX for RL.","archived":false,"fork":false,"pushed_at":"2025-07-08T09:04:36.000Z","size":16845,"stargazers_count":43,"open_issues_count":3,"forks_count":0,"subscribers_count":13,"default_branch":"main","last_synced_at":"2025-07-08T10:24:01.676Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leggedrobotics.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-03-30T13:02:37.000Z","updated_at":"2025-07-01T12:03:56.000Z","dependencies_parsed_at":"2025-02-27T18:24:24.662Z","dependency_job_id":"8e38bcfd-318f-4015-85c4-96eaf80a9f59","html_url":"https://github.com/leggedrobotics/terra","commit_stats":null,"previous_names":["leggedrobotics/terra"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/leggedrobotics/terra","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leggedrobotics%2Fterra","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leggedrobotics%2Fterra/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leggedrobotics%2Fterra/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leggedrobotics%2Fterra/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leggedrobotics","download_url":"https://codeload.github.com/leggedrobotics/terra/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leggedrobotics%2Fterra/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264721592,"owners_count":23653961,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-12T14:11:48.821Z","updated_at":"2025-10-03T21:33:24.547Z","avatar_url":"https://github.com/leggedrobotics.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🌍 Terra - Earthwork planning environment in JAX\n\n![img](assets/overview.gif)\n\nTerra is a flexible and abstracted grid world environment for training intelligent agents in the context of earthworks planning. It makes it possible to approach motion and excavation high-level planning as a reinforcement learning problem, providing a multi-GPU JAX-accelerated environment. We show that we can train an agent capable of planning earthworks in trenches and foundations environments in less than 1 minute on 8 Nvidia RTX-4090 GPUs.\n\n## Features\n- 🚜 Two Agent Types: Wheeled and tracked excavator embodiments for different types of actions\n- 🏞️ Realistic Maps: Up-to-3-axes trenches and building foundations with obstacles and dumping constraints\n- 🔥 Performance: Easily scale to more than 1M steps per second on a single GPU\n- 🚀 Scaling: Out of the box multi-device training\n- 📖 Curriculum: Customizable RL curriculum via config interface\n- 🔧 Tooling: Visualization, evaluation, manual play, and maps inspection scripts\n- 🏌 Baselines: We provide baseline results and PPO-based training scripts inspired from [purejaxrl](https://github.com/luchris429/purejaxrl) and [xland-minigrid](https://github.com/corl-team/xland-minigrid)\n\n## Installation\nClone the repo, and if you want to use Terra in your project use \n~~~\npip install -e .\n~~~\nYou can check out [terra-baselines](https://github.com/leggedrobotics/rl-excavation-planning) for an installation workflow example.\n\n### JAX\nThe JAX installation is hardware-dependent and therefore needs to be done separately. Follow [this link](https://jax.readthedocs.io/en/latest/installation.html) to install the right one for you.\n\n## Usage\nThe standard workflow is made of the following steps:\n1. Generate the maps by following this [README](https://github.com/leggedrobotics/terra/blob/main/terra/env_generation/README.md) (you can check out a preview of the generated maps in the `data/` folder)\n2. Set up the curriculum in `config.py`\n2. Build your own training script or use the ready-to-use script from our [terra-baselines](https://github.com/leggedrobotics/rl-excavation-planning).\n3. Train 🚀\n4. Run [evaluations](https://github.com/leggedrobotics/rl-excavation-planning/blob/master/eval.py) and [visualization](https://github.com/leggedrobotics/rl-excavation-planning/blob/master/visualize.py).\n\n# Environment Setup Instructions\n\nThis repository includes configuration files to help you set up the required environment for this project.\n\n## Using Conda Environment (Recommended)\n\nThe `environment.yml` file contains all the necessary dependencies to reproduce the project environment named \"terra\" with Python 3.12.2.\n\n### Creating the Environment\n\nTo create a new conda environment from the provided `environment.yml` file, run:\n\n```bash\nconda env create -f environment.yml\n```\n\nThis command will create a new environment named \"terra\" with all the specified dependencies.\n\n### Activating the Environment\n\nAfter creating the environment, activate it with:\n\n```bash\nconda activate terra\n```\n\n### Installing Terra and JAX\n\nAfter activating the environment it is necessary to install Terra\n\n```bash\npip install -e .\n```\n\nand [JAX](https://docs.jax.dev/en/latest/installation.html).\n\nAt the moment you should use jaxlib and jax version \u003c= 0.4.26 as `jax.tree_map` is deprecated in newer versions\n\n```bash\npip install -U \"jax[cuda12]==0.4.26\" jaxlib==0.4.26+cuda12.cudnn89 -f https://storage.googleapis.com/jax-releases/jax_cuda_releases.html\n```\n\nWith GPU (NVIDIA, CUDA 12):\n\n```bash\npip install -U \"jax[cuda12]\"\n```\n\n### Verifying the Environment\n\nTo verify that the environment was set up correctly, you can:\n\n1. Check that you're in the correct environment:\n   ```bash\n   conda info\n   ```\n   The active environment should be displayed as \"terra\".\n\n2. List all installed packages:\n   ```bash\n   conda list\n   ```\n\n3. Check Python version:\n   ```bash\n   python --version\n   ```\n   This should output \"Python 3.12.2\"\n\n## Environment Files: requirements.txt vs environment.yml\n\n### environment.yml\n\nThe `environment.yml` file is used by conda to create environments and has several advantages:\n- Specifies the Python version\n- Can include conda and pip dependencies in one file\n- Can include dependencies from multiple channels\n- Resolves dependencies more effectively than pip alone\n- Handles non-Python dependencies (e.g., C libraries)\n\n### requirements.txt\n\nThe `requirements.txt` file is a standard pip requirements file that specifies Python packages to be installed with pip. This file:\n- Lists Python dependencies only\n- Can be used with `pip install -r requirements.txt`\n- Doesn't specify Python version\n- Doesn't handle non-Python dependencies\n\nFor this project, the `environment.yml` file is the recommended way to set up your environment as it ensures all dependencies (including the correct Python version) are properly installed.\n\n## Updating the Environment\n\nIf you need to update the environment after changes to the `environment.yml` file:\n\n```bash\nconda env update -f environment.yml --prune\n```\n\nThe `--prune` option removes dependencies that are no longer specified in the updated file.\n\n\n### Basic Usage\n``` python\nimport jax\nfrom terra.env import TerraEnvBatch\nfrom terra.config import EnvConfig\n\nkey = jax.random.PRNGKey(0)\nkey, reset_key, step_key = jax.random.split(key, 3)\n\n# create Terra and configs\nenv = TerraEnvBatch()\nenv_params = EnvConfig()\n\n# jitted reset and step functions\ntimestep = env.reset(env_params, reset_key)\ntimestep = env.step(timestep, action, step_key)\n```\n\n### Map generation\nRunning the standard map generation will produce the following folder structure. This includes foundations and trenches, and additional curriculum maps that help with the training in case the sparse reward strategy is used.\n```\n- data\n    - custom  \u003c-- custom made maps for training special behaviour\n    - openstreet\n    - terra\n        - foundations\n        - trenches\n        - train  \u003c- npy maps formatter for terra\n            - trenches  \u003c-- trenches with 1 to 3 intersecting axes\n            - foundations  \u003c-- building foundations from OpenStreetMap\n                - dumpability  \u003c-- encodes where the agent can dump\n                - images  \u003c-- encodes the target dig profile\n                - occupancy  \u003c-- encodes the obstacles\n            - foundations_large  \u003c-- same as foundations but bigger\n            - custom\n```\n\n### Training Configurations\nIn Terra the settings are expressed as curriculum levels. To set the levels of the training, you can edit the `config.py` file. For example, if you want to start your training with dense rewards on foundations and then shift to shorter episodes with sparse rewards, you can set the curriculum as follows.\n``` python\nclass CurriculumGlobalConfig(NamedTuple):\n    increase_level_threshold: int = 3\n    decrease_level_threshold: int = 10\n    \n    levels = [\n        {\n            \"maps_path\": \"terra/foundations\",\n            \"max_steps_in_episode\": 300,\n            \"rewards_type\": RewardsType.DENSE,\n            \"apply_trench_rewards\": False,\n        },\n        {\n            \"maps_path\": \"terra/trenches/single\",\n            \"max_steps_in_episode\": 200,\n            \"rewards_type\": RewardsType.SPARSE,\n            \"apply_trench_rewards\": True,\n        }\n    ]\n```\nNote that `apply_trench_rewards` should be `True` if you are training on trenches. This enables an additional reward that penalizes the distance of the agent from any trench axis at dig time, pushing the agent to be aligned to them.\n\nTo select the embodiment to use, set the following to either `TrackedAction` or `WheeledAction`. Check out `state.py` for the documentation of the embodiment-specific state transitions.\n``` python\nclass BatchConfig(NamedTuple):\n    action_type: Action = TrackedAction\n```\n\n## Tools 🔧\nWe provide debugging tools to explore Terra maps and play with the different agents.\n\nYou can play on a single environment using your keyboard with\n``` python\nDATASET_PATH=/path/to/dataset DATASET_SIZE=\u003cnum_maps_per_type\u003e python -m terra.viz.main_manual\n```\nand you can inspect the generated maps with\n``` python\nDATASET_PATH=/path/to/dataset DATASET_SIZE=\u003cnum_maps_per_type\u003e python -m terra.viz.play\n```\nnote that these scripts assume that the maps are stored in the `data/` folder.\n\n## Rules 🔮\nIn Terra the agent can move around, dig, and dump terrain. The goal of the agent is to dig the target shape given at the beginning of the episode, planning around obstacles and dumping constraints. The target map defines all the tiles that can be dug, and the action map stores the progress. Tiles are dug in batches, where a batch is defined by the conical section representing the full reach of the excavator arm for a given base and cabin pose. Therefore, with a `DO` action, the agent digs all the tiles in the target map that are within reach, and subsequently with another `DO` action it distributes the dirt evenly on the dumpable tiles within reach.\n\n### Agent Types\nTwo types of excavators are abstracted in Terra: tracked and wheeled. The difference is that the tracked excavator is able to turn the base on the spot whereas the wheeled turns by doing an L-shaped movement (e.g. forward-turn-forward).\n\n### Map Types\nTerra comes with two types of maps: foundations and trenches. Foundations are produced by projecting real building profiles from OpenStreetMap on the grid map. Trenches are procedurally generated and are divided in three categories based on the number of axes the trench has (1 to 3). All the maps have additional layers to encode obstacles, regions where the excavator can't dump terrain (e.g. roads), and regions where the excavator needs to dump all the terrain to terminate the episode (terminal dumping areas). Check out `map.py` for the documentation of the map layering and logic. \n\n## Observation Space 🔍\nThe agent in Terra perceives the environment through a rich observation space that provides comprehensive information about the state of the world and the agent itself. The observation is a dictionary with the following components:\n\n- **agent_states**: A 6-dimensional vector containing:\n  - Position of the base (x, y coordinates)\n  - Base rotation angle\n  - Cabin rotation angle\n  - Whether the agent is loaded with dirt (0 or 1)\n  - Wheel angle (in case of wheeled digger)\n\n- **Local Maps**: The agent has access to local maps representing different aspects of the environment from the agent's perspective:\n  - **local_map_action_neg/pos**: Current state of the terrain (negative/positive height) within the agent's reach\n  - **local_map_target_neg/pos**: Target digging profile (negative/positive height) within reach\n  - **local_map_dumpability**: Areas where the agent can dump soil within reach\n  - **local_map_obstacles**: Obstacles within the agent's reach\n\n- **Global Maps**: Full maps of the environment:\n  - **action_map**: Current state of the terrain across the entire map\n  - **target_map**: Target digging profile across the entire map\n  - **traversability_mask**: Areas where the agent can navigate\n  - **dumpability_mask**: Areas where the agent can dump soil\n  - **padding_mask**: Areas with obstacles\n\n- **Agent Dimensions**:\n  - **agent_width**: Width of the agent\n  - **agent_height**: Height of the agent\n\nThis rich observation space allows the agent to understand both its immediate surroundings and the global state of the environment, enabling effective planning for navigation, digging, and dumping operations.\n\n## Performance 🔥\nWe benchmark the environments by measuring the runtime of our PPO algorithm including environment steps and model update on Nvidia RTX-4090 GPUs. For all the experiments we keep constant 32 steps, 32 minibatches, and 1 update epoch.\n\nScaling on single device             |  Scaling across devices\n:-------------------------:|:-------------------------:\n![](assets/scaling-envs.png)  |  ![](assets/scaling-devices.png)\n\n## Baselines 🎮\nWe release a set of baselines and checkpoints in [terra-baselines](https://github.com/leggedrobotics/rl-excavation-planning).\n\n## Citation\nIf you use this code in your research or project, please cite the following:\n```\n@misc{terra,\n    title={Terra - Earthwork planning environment in JAX},\n    author={Antonio Arbues, Lorenzo Terenzi},\n    howpublished={\\url{https://github.com/leggedrobotics/terra}},\n    year={2024}\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleggedrobotics%2Fterra","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleggedrobotics%2Fterra","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleggedrobotics%2Fterra/lists"}