Buckets:
| <meta charset="utf-8" /><meta name="hf:doc:metadata" content="{"title":"Environment Processors","local":"environment-processors","sections":[{"title":"Why Environment Processors?","local":"why-environment-processors","sections":[],"depth":2},{"title":"The Processing Pipeline","local":"the-processing-pipeline","sections":[],"depth":2},{"title":"The Benefits","local":"the-benefits","sections":[{"title":"1. Separation of Concerns","local":"1-separation-of-concerns","sections":[],"depth":3},{"title":"2. Flexibility and Reusability","local":"2-flexibility-and-reusability","sections":[],"depth":3},{"title":"4. Cleaner Environment Code","local":"4-cleaner-environment-code","sections":[],"depth":3}],"depth":2},{"title":"Using Environment Processors","local":"using-environment-processors","sections":[{"title":"Factory Function","local":"factory-function","sections":[],"depth":3},{"title":"Implementation in envs/factory.py","local":"implementation-in-envsfactorypy","sections":[],"depth":3},{"title":"Integration in Evaluation","local":"integration-in-evaluation","sections":[],"depth":3}],"depth":2},{"title":"Example: LIBERO Environment Processor","local":"example-libero-environment-processor","sections":[{"title":"Why These Transformations?","local":"why-these-transformations","sections":[],"depth":3}],"depth":2},{"title":"Adding Environment Processors for New Environments","local":"adding-environment-processors-for-new-environments","sections":[{"title":"1. Create the Processor Step","local":"1-create-the-processor-step","sections":[],"depth":3},{"title":"2. Update Your EnvConfig Subclass","local":"2-update-your-envconfig-subclass","sections":[],"depth":3},{"title":"3. Use in Evaluation","local":"3-use-in-evaluation","sections":[],"depth":3}],"depth":2},{"title":"Future: Environment Postprocessors","local":"future-environment-postprocessors","sections":[{"title":"Action Space Transformations","local":"action-space-transformations","sections":[],"depth":3},{"title":"Coordinate System Conversions","local":"coordinate-system-conversions","sections":[],"depth":3}],"depth":2},{"title":"Best Practices","local":"best-practices","sections":[],"depth":2},{"title":"Summary","local":"summary","sections":[],"depth":2}],"depth":1}"> | |
| <link href="/docs/lerobot/pr_3313/en/_app/immutable/assets/0.e3b0c442.css" rel="modulepreload"> | |
| <link rel="modulepreload" href="/docs/lerobot/pr_3313/en/_app/immutable/entry/start.d3f1c0f3.js"> | |
| <link rel="modulepreload" href="/docs/lerobot/pr_3313/en/_app/immutable/chunks/scheduler.eb244325.js"> | |
| <link rel="modulepreload" href="/docs/lerobot/pr_3313/en/_app/immutable/chunks/singletons.1f33814c.js"> | |
| <link rel="modulepreload" href="/docs/lerobot/pr_3313/en/_app/immutable/chunks/index.3c23fb4b.js"> | |
| <link rel="modulepreload" href="/docs/lerobot/pr_3313/en/_app/immutable/chunks/paths.17f05d75.js"> | |
| <link rel="modulepreload" href="/docs/lerobot/pr_3313/en/_app/immutable/entry/app.04bb7687.js"> | |
| <link rel="modulepreload" href="/docs/lerobot/pr_3313/en/_app/immutable/chunks/preload-helper.b00aacbc.js"> | |
| <link rel="modulepreload" href="/docs/lerobot/pr_3313/en/_app/immutable/chunks/index.3fe63ad3.js"> | |
| <link rel="modulepreload" href="/docs/lerobot/pr_3313/en/_app/immutable/nodes/0.07fbe93e.js"> | |
| <link rel="modulepreload" href="/docs/lerobot/pr_3313/en/_app/immutable/chunks/each.e59479a4.js"> | |
| <link rel="modulepreload" href="/docs/lerobot/pr_3313/en/_app/immutable/nodes/14.a77a1768.js"> | |
| <link rel="modulepreload" href="/docs/lerobot/pr_3313/en/_app/immutable/chunks/CopyLLMTxtMenu.d0c64540.js"> | |
| <link rel="modulepreload" href="/docs/lerobot/pr_3313/en/_app/immutable/chunks/MermaidChart.svelte_svelte_type_style_lang.6453902c.js"> | |
| <link rel="modulepreload" href="/docs/lerobot/pr_3313/en/_app/immutable/chunks/CodeBlock.48dd2cc2.js"><!-- HEAD_svelte-u9bgzb_START --><meta name="hf:doc:metadata" content="{"title":"Environment Processors","local":"environment-processors","sections":[{"title":"Why Environment Processors?","local":"why-environment-processors","sections":[],"depth":2},{"title":"The Processing Pipeline","local":"the-processing-pipeline","sections":[],"depth":2},{"title":"The Benefits","local":"the-benefits","sections":[{"title":"1. Separation of Concerns","local":"1-separation-of-concerns","sections":[],"depth":3},{"title":"2. Flexibility and Reusability","local":"2-flexibility-and-reusability","sections":[],"depth":3},{"title":"4. Cleaner Environment Code","local":"4-cleaner-environment-code","sections":[],"depth":3}],"depth":2},{"title":"Using Environment Processors","local":"using-environment-processors","sections":[{"title":"Factory Function","local":"factory-function","sections":[],"depth":3},{"title":"Implementation in envs/factory.py","local":"implementation-in-envsfactorypy","sections":[],"depth":3},{"title":"Integration in Evaluation","local":"integration-in-evaluation","sections":[],"depth":3}],"depth":2},{"title":"Example: LIBERO Environment Processor","local":"example-libero-environment-processor","sections":[{"title":"Why These Transformations?","local":"why-these-transformations","sections":[],"depth":3}],"depth":2},{"title":"Adding Environment Processors for New Environments","local":"adding-environment-processors-for-new-environments","sections":[{"title":"1. Create the Processor Step","local":"1-create-the-processor-step","sections":[],"depth":3},{"title":"2. Update Your EnvConfig Subclass","local":"2-update-your-envconfig-subclass","sections":[],"depth":3},{"title":"3. Use in Evaluation","local":"3-use-in-evaluation","sections":[],"depth":3}],"depth":2},{"title":"Future: Environment Postprocessors","local":"future-environment-postprocessors","sections":[{"title":"Action Space Transformations","local":"action-space-transformations","sections":[],"depth":3},{"title":"Coordinate System Conversions","local":"coordinate-system-conversions","sections":[],"depth":3}],"depth":2},{"title":"Best Practices","local":"best-practices","sections":[],"depth":2},{"title":"Summary","local":"summary","sections":[],"depth":2}],"depth":1}"><!-- HEAD_svelte-u9bgzb_END --> <p></p> <div class="items-center shrink-0 min-w-[100px] max-sm:min-w-[50px] justify-end ml-auto flex" style="float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"><div class="inline-flex rounded-md max-sm:rounded-sm"><button class="inline-flex items-center gap-1 h-7 max-sm:h-7 px-2 max-sm:px-1.5 text-sm font-medium text-gray-800 border border-r-0 rounded-l-md max-sm:rounded-l-sm border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-live="polite"><span class="inline-flex items-center justify-center rounded-md p-0.5 max-sm:p-0 hover:text-gray-800 dark:hover:text-gray-200"><svg class="sm:size-3.5 size-3" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg></span> <span>Copy page</span></button> <button class="inline-flex items-center justify-center w-6 max-sm:w-5 h-7 max-sm:h-7 disabled:pointer-events-none text-sm text-gray-500 hover:text-gray-700 dark:hover:text-white rounded-r-md max-sm:rounded-r-sm border border-l transition border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-haspopup="menu" aria-expanded="false" aria-label="Open copy menu"><svg class="transition-transform text-gray-400 overflow-visible sm:size-3.5 size-3 rotate-0" width="1em" height="1em" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1L6 6L11 1" stroke="currentColor"></path></svg></button></div> </div> <h1 class="relative group"><a id="environment-processors" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#environment-processors"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Environment Processors</span></h1> <p data-svelte-h="svelte-18yz6qb">Environment processors are a critical layer in LeRobot’s data processing architecture that handle <strong>environment-specific</strong> transformations, separate from policy-specific processing. This separation of concerns enables cleaner code, better modularity, and easier experimentation with different environments and policies.</p> <h2 class="relative group"><a id="why-environment-processors" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#why-environment-processors"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Why Environment Processors?</span></h2> <p data-svelte-h="svelte-ri9h5i">When working with different robot environments (LIBERO, MetaWorld, Aloha, etc.), each environment often has unique data formats, coordinate systems, and conventions that need standardization <strong>before</strong> policy processing. Without environment processors, these transformations would be:</p> <ol data-svelte-h="svelte-gxqwp2"><li><strong>Hardcoded in environment code</strong> - Making it difficult to experiment with different state representations</li> <li><strong>Duplicated across policies</strong> - Each policy would need to handle environment-specific quirks</li> <li><strong>Mixed with policy logic</strong> - Violating separation of concerns and making debugging harder</li></ol> <p data-svelte-h="svelte-tv2fpz">Environment processors solve this by providing a <strong>dedicated processing layer</strong> between raw environment observations and policy inputs.</p> <h2 class="relative group"><a id="the-processing-pipeline" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#the-processing-pipeline"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>The Processing Pipeline</span></h2> <p data-svelte-h="svelte-11scm6i">Here’s how data flows through the complete processing pipeline during evaluation:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-comment"># In lerobot_eval.py rollout() function:</span> | |
| <span class="hljs-comment"># 1. Raw environment observation (numpy arrays, various formats)</span> | |
| raw_observation = env.step(action) | |
| <span class="hljs-comment"># 2. Convert numpy to torch, normalize images [0,1]</span> | |
| observation = preprocess_observation(raw_observation) | |
| <span class="hljs-comment"># 3. Add task metadata (for multi-task environments)</span> | |
| observation = add_envs_task(env, observation) | |
| <span class="hljs-comment"># 4. ENVIRONMENT-SPECIFIC preprocessing (NEW!)</span> | |
| <span class="hljs-comment"># - Flatten robot states</span> | |
| <span class="hljs-comment"># - Rotate images to match dataset conventions</span> | |
| <span class="hljs-comment"># - Handle environment-specific coordinate systems</span> | |
| observation = env_preprocessor(observation) | |
| <span class="hljs-comment"># 5. POLICY-SPECIFIC preprocessing</span> | |
| <span class="hljs-comment"># - Normalize with dataset statistics</span> | |
| <span class="hljs-comment"># - Add batch dimensions</span> | |
| <span class="hljs-comment"># - Move to GPU</span> | |
| <span class="hljs-comment"># - Tokenize language instructions</span> | |
| observation = preprocessor(observation) | |
| <span class="hljs-comment"># 6. Policy inference</span> | |
| action = policy.select_action(observation) | |
| <span class="hljs-comment"># 7. POLICY-SPECIFIC postprocessing</span> | |
| <span class="hljs-comment"># - Unnormalize actions</span> | |
| <span class="hljs-comment"># - Remove batch dimensions</span> | |
| action = postprocessor(action) | |
| <span class="hljs-comment"># 8. ENVIRONMENT-SPECIFIC postprocessing (NEW!)</span> | |
| <span class="hljs-comment"># - Convert action formats if needed</span> | |
| <span class="hljs-comment"># - Apply environment-specific constraints</span> | |
| action_transition = {<span class="hljs-string">"action"</span>: action} | |
| action_transition = env_postprocessor(action_transition) | |
| action = action_transition[<span class="hljs-string">"action"</span>] | |
| <span class="hljs-comment"># 9. Execute in environment</span> | |
| env.step(action)<!-- HTML_TAG_END --></pre></div> <h2 class="relative group"><a id="the-benefits" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#the-benefits"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>The Benefits</span></h2> <h3 class="relative group"><a id="1-separation-of-concerns" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#1-separation-of-concerns"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>1. Separation of Concerns</span></h3> <p data-svelte-h="svelte-17n50nh">Environment processors handle transformations specific to the <strong>environment’s data format</strong>, while policy processors handle transformations specific to the <strong>model’s requirements</strong>.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-comment"># ❌ Before: Mixed concerns</span> | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">LiberoVLAPolicy</span>: | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">preprocess</span>(<span class="hljs-params">self, obs</span>): | |
| <span class="hljs-comment"># Environment-specific: Flatten robot state (shouldn't be in policy!)</span> | |
| state = self._flatten_robot_state(obs[<span class="hljs-string">"robot_state"</span>]) | |
| <span class="hljs-comment"># Policy-specific: Normalize with dataset stats</span> | |
| state = self.normalizer(state) | |
| <span class="hljs-keyword">return</span> state | |
| <span class="hljs-comment"># ✅ After: Clear separation</span> | |
| <span class="hljs-comment"># Environment processor: Handles LIBERO's nested robot state</span> | |
| env_preprocessor = LiberoProcessorStep() <span class="hljs-comment"># Flattens robot_state</span> | |
| <span class="hljs-comment"># Policy processor: Handles model requirements</span> | |
| policy_preprocessor = NormalizerProcessorStep(stats=dataset_stats)<!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="2-flexibility-and-reusability" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#2-flexibility-and-reusability"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>2. Flexibility and Reusability</span></h3> <p data-svelte-h="svelte-tkwoku">The same policy can work with different environment processors, and the same environment processor can work with different policies:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-comment"># Use SmolVLA policy with LIBERO environment</span> | |
| <span class="hljs-comment"># Use SmolVLA policy with LIBERO environment</span> | |
| libero_preprocessor, libero_postprocessor = make_env_pre_post_processors( | |
| env_cfg=libero_cfg, | |
| policy_cfg=smolvla_cfg, | |
| ) | |
| smolvla_preprocessor, smolvla_postprocessor = make_pre_post_processors(smolvla_cfg) | |
| <span class="hljs-comment"># Or use ACT policy with the same LIBERO environment</span> | |
| libero_preprocessor, libero_postprocessor = make_env_pre_post_processors( | |
| env_cfg=libero_cfg, | |
| policy_cfg=act_cfg, | |
| ) | |
| act_preprocessor, act_postprocessor = make_pre_post_processors(act_cfg) | |
| ```python | |
| <span class="hljs-comment"># Use SmolVLA policy with LIBERO environment</span> | |
| libero_preprocessor, libero_postprocessor = make_env_pre_post_processors( | |
| env_cfg=libero_cfg, | |
| policy_cfg=smolvla_cfg, | |
| ) | |
| smolvla_preprocessor, smolvla_postprocessor = make_pre_post_processors(smolvla_cfg) | |
| <span class="hljs-comment"># Or use ACT policy with the same LIBERO environment</span> | |
| libero_preprocessor, libero_postprocessor = make_env_pre_post_processors( | |
| env_cfg=libero_cfg, | |
| policy_cfg=act_cfg, | |
| ) | |
| act_preprocessor, act_postprocessor = make_pre_post_processors(act_cfg) | |
| <span class="hljs-comment">### 3. **Easier Experimentation**</span> | |
| Want to <span class="hljs-keyword">try</span> different state representations <span class="hljs-keyword">for</span> LIBERO? Just create a new processor: | |
| ```python | |
| <span class="hljs-comment"># Original: 8D state (pos + quat→axisangle + gripper)</span> | |
| <span class="hljs-meta">@ProcessorStepRegistry.register(<span class="hljs-params"><span class="hljs-string">"libero_processor"</span></span>)</span> | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">LiberoProcessorStep</span>(<span class="hljs-title class_ inherited__">ObservationProcessorStep</span>): | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">_process_observation</span>(<span class="hljs-params">self, obs</span>): | |
| eef_pos = robot_state[<span class="hljs-string">"eef"</span>][<span class="hljs-string">"pos"</span>] <span class="hljs-comment"># 3D</span> | |
| eef_axisangle = quat2axisangle(quat) <span class="hljs-comment"># 3D</span> | |
| gripper = robot_state[<span class="hljs-string">"gripper"</span>][<span class="hljs-string">"qpos"</span>] <span class="hljs-comment"># 2D</span> | |
| state = torch.cat([eef_pos, eef_axisangle, gripper], dim=-<span class="hljs-number">1</span>) <span class="hljs-comment"># 8D</span> | |
| <span class="hljs-keyword">return</span> state | |
| <span class="hljs-comment"># Experiment: Add velocity for better control</span> | |
| <span class="hljs-meta">@ProcessorStepRegistry.register(<span class="hljs-params"><span class="hljs-string">"libero_velocity_processor"</span></span>)</span> | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">LiberoVelocityProcessorStep</span>(<span class="hljs-title class_ inherited__">ObservationProcessorStep</span>): | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">_process_observation</span>(<span class="hljs-params">self, obs</span>): | |
| <span class="hljs-comment"># Include velocities for 14D state</span> | |
| eef_pos = robot_state[<span class="hljs-string">"eef"</span>][<span class="hljs-string">"pos"</span>] <span class="hljs-comment"># 3D</span> | |
| eef_axisangle = quat2axisangle(quat) <span class="hljs-comment"># 3D</span> | |
| eef_vel = robot_state[<span class="hljs-string">"eef"</span>][<span class="hljs-string">"vel"</span>] <span class="hljs-comment"># 3D (NEW)</span> | |
| gripper_pos = robot_state[<span class="hljs-string">"gripper"</span>][<span class="hljs-string">"qpos"</span>] <span class="hljs-comment"># 2D</span> | |
| gripper_vel = robot_state[<span class="hljs-string">"gripper"</span>][<span class="hljs-string">"qvel"</span>] <span class="hljs-comment"># 3D (NEW)</span> | |
| state = torch.cat([eef_pos, eef_axisangle, eef_vel, | |
| gripper_pos, gripper_vel], dim=-<span class="hljs-number">1</span>) <span class="hljs-comment"># 14D</span> | |
| <span class="hljs-keyword">return</span> state<!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="4-cleaner-environment-code" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#4-cleaner-environment-code"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>4. Cleaner Environment Code</span></h3> <p data-svelte-h="svelte-ae3ylm">Environments expose <strong>all available data</strong> without needing to know what downstream models will use:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-comment"># LIBERO environment exposes full robot state</span> | |
| observation = { | |
| <span class="hljs-string">"pixels"</span>: {<span class="hljs-string">"image"</span>: img, <span class="hljs-string">"image2"</span>: img2}, | |
| <span class="hljs-string">"robot_state"</span>: { | |
| <span class="hljs-string">"eef"</span>: {<span class="hljs-string">"pos"</span>: ..., <span class="hljs-string">"quat"</span>: ..., <span class="hljs-string">"vel"</span>: ..., <span class="hljs-string">"mat"</span>: ..., <span class="hljs-string">"axisangle"</span>: ...}, | |
| <span class="hljs-string">"gripper"</span>: {<span class="hljs-string">"qpos"</span>: ..., <span class="hljs-string">"qvel"</span>: ...}, | |
| <span class="hljs-string">"joints"</span>: {<span class="hljs-string">"pos"</span>: ..., <span class="hljs-string">"vel"</span>: ...} | |
| } | |
| } | |
| <span class="hljs-comment"># Environment processor decides what to use</span> | |
| <span class="hljs-comment"># Policy processor handles model-specific transformations</span><!-- HTML_TAG_END --></pre></div> <h2 class="relative group"><a id="using-environment-processors" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#using-environment-processors"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Using Environment Processors</span></h2> <h3 class="relative group"><a id="factory-function" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#factory-function"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Factory Function</span></h3> <p data-svelte-h="svelte-1rcg1m5">The <code>make_env_pre_post_processors</code> function follows the same pattern as <code>make_pre_post_processors</code> for policies:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> lerobot.envs <span class="hljs-keyword">import</span> make_env_pre_post_processors, PushtEnv | |
| <span class="hljs-keyword">from</span> lerobot.envs.configs <span class="hljs-keyword">import</span> LiberoEnv | |
| <span class="hljs-comment"># For LIBERO: Returns LiberoProcessorStep in preprocessor</span> | |
| libero_cfg = LiberoEnv(task=<span class="hljs-string">"libero_spatial"</span>, camera_name=[<span class="hljs-string">"agentview"</span>]) | |
| env_preprocessor, env_postprocessor = make_env_pre_post_processors(libero_cfg) | |
| <span class="hljs-comment"># For other environments: Returns identity processors (no-op)</span> | |
| pusht_cfg = PushtEnv() | |
| env_preprocessor, env_postprocessor = make_env_pre_post_processors(pusht_cfg)<!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="implementation-in-envsfactorypy" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#implementation-in-envsfactorypy"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Implementation in envs/factory.py</span></h3> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">def</span> <span class="hljs-title function_">make_env_pre_post_processors</span>(<span class="hljs-params"> | |
| env_cfg: EnvConfig, | |
| </span>) -> <span class="hljs-built_in">tuple</span>[ | |
| PolicyProcessorPipeline[<span class="hljs-built_in">dict</span>[<span class="hljs-built_in">str</span>, <span class="hljs-type">Any</span>], <span class="hljs-built_in">dict</span>[<span class="hljs-built_in">str</span>, <span class="hljs-type">Any</span>]], | |
| PolicyProcessorPipeline[<span class="hljs-built_in">dict</span>[<span class="hljs-built_in">str</span>, <span class="hljs-type">Any</span>], <span class="hljs-built_in">dict</span>[<span class="hljs-built_in">str</span>, <span class="hljs-type">Any</span>]], | |
| ]: | |
| <span class="hljs-string">""" | |
| Create preprocessor and postprocessor pipelines for environment observations. | |
| Args: | |
| env_cfg: The configuration of the environment. | |
| Returns: | |
| A tuple containing: | |
| - preprocessor: Pipeline that processes environment observations | |
| - postprocessor: Pipeline that processes environment outputs | |
| """</span> | |
| <span class="hljs-comment"># For LIBERO environments, add the LiberoProcessorStep to preprocessor</span> | |
| <span class="hljs-keyword">if</span> <span class="hljs-built_in">isinstance</span>(env_cfg, LiberoEnv) <span class="hljs-keyword">or</span> <span class="hljs-string">"libero"</span> <span class="hljs-keyword">in</span> env_cfg.<span class="hljs-built_in">type</span>: | |
| preprocessor = PolicyProcessorPipeline(steps=[LiberoProcessorStep()]) | |
| <span class="hljs-keyword">else</span>: | |
| <span class="hljs-comment"># For all other environments, return an identity preprocessor</span> | |
| preprocessor = PolicyProcessorPipeline(steps=[]) | |
| <span class="hljs-comment"># Postprocessor is currently identity for all environments</span> | |
| <span class="hljs-comment"># Future: Could add environment-specific action transformations</span> | |
| postprocessor = PolicyProcessorPipeline(steps=[]) | |
| <span class="hljs-keyword">return</span> preprocessor, postprocessor<!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="integration-in-evaluation" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#integration-in-evaluation"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Integration in Evaluation</span></h3> <p data-svelte-h="svelte-zugfyu">In <code>lerobot_eval.py</code>, the environment processors are created once and used throughout:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">def</span> <span class="hljs-title function_">eval_main</span>(<span class="hljs-params">cfg: EvalPipelineConfig</span>): | |
| <span class="hljs-comment"># Create environment</span> | |
| envs = make_env(cfg.env, n_envs=cfg.<span class="hljs-built_in">eval</span>.batch_size) | |
| <span class="hljs-comment"># Create policy</span> | |
| policy = make_policy(cfg=cfg.policy, env_cfg=cfg.env) | |
| <span class="hljs-comment"># Create policy processors</span> | |
| preprocessor, postprocessor = make_pre_post_processors( | |
| policy_cfg=cfg.policy, | |
| pretrained_path=cfg.policy.pretrained_path, | |
| ) | |
| <span class="hljs-comment"># Create environment processors (NEW!)</span> | |
| env_preprocessor, env_postprocessor = make_env_pre_post_processors(env_cfg=cfg.env) | |
| <span class="hljs-comment"># Run evaluation with both processor types</span> | |
| eval_policy_all( | |
| envs=envs, | |
| policy=policy, | |
| env_preprocessor=env_preprocessor, <span class="hljs-comment"># Environment-specific</span> | |
| env_postprocessor=env_postprocessor, <span class="hljs-comment"># Environment-specific</span> | |
| preprocessor=preprocessor, <span class="hljs-comment"># Policy-specific</span> | |
| postprocessor=postprocessor, <span class="hljs-comment"># Policy-specific</span> | |
| n_episodes=cfg.<span class="hljs-built_in">eval</span>.n_episodes, | |
| )<!-- HTML_TAG_END --></pre></div> <h2 class="relative group"><a id="example-libero-environment-processor" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#example-libero-environment-processor"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Example: LIBERO Environment Processor</span></h2> <p data-svelte-h="svelte-aj30fp">The <code>LiberoProcessorStep</code> demonstrates a real-world environment processor:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-keyword">from</span> lerobot.processor <span class="hljs-keyword">import</span> ObservationProcessorStep | |
| <span class="hljs-meta">@dataclass</span> | |
| <span class="hljs-meta">@ProcessorStepRegistry.register(<span class="hljs-params">name=<span class="hljs-string">"libero_processor"</span></span>)</span> | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">LiberoProcessorStep</span>(<span class="hljs-title class_ inherited__">ObservationProcessorStep</span>): | |
| <span class="hljs-string">""" | |
| Processes LIBERO observations into the LeRobot format. | |
| **State Processing:** | |
| - Extracts end-effector position (3D) | |
| - Converts quaternion to axis-angle representation (3D) | |
| - Extracts gripper joint positions (2D) | |
| - Concatenates into 8D state vector | |
| **Image Processing:** | |
| - Rotates images 180° to match HuggingFaceVLA/libero convention | |
| """</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">_process_observation</span>(<span class="hljs-params">self, observation</span>): | |
| processed_obs = observation.copy() | |
| <span class="hljs-comment"># Process images: Flip 180° for camera convention</span> | |
| <span class="hljs-keyword">for</span> key <span class="hljs-keyword">in</span> <span class="hljs-built_in">list</span>(processed_obs.keys()): | |
| <span class="hljs-keyword">if</span> key.startswith(<span class="hljs-string">"observation.images."</span>): | |
| img = processed_obs[key] | |
| img = torch.flip(img, dims=[<span class="hljs-number">2</span>, <span class="hljs-number">3</span>]) <span class="hljs-comment"># Flip H and W</span> | |
| processed_obs[key] = img | |
| <span class="hljs-comment"># Process robot_state: Flatten to 8D vector</span> | |
| <span class="hljs-keyword">if</span> <span class="hljs-string">"observation.robot_state"</span> <span class="hljs-keyword">in</span> processed_obs: | |
| robot_state = processed_obs.pop(<span class="hljs-string">"observation.robot_state"</span>) | |
| eef_pos = robot_state[<span class="hljs-string">"eef"</span>][<span class="hljs-string">"pos"</span>] <span class="hljs-comment"># (B, 3)</span> | |
| eef_quat = robot_state[<span class="hljs-string">"eef"</span>][<span class="hljs-string">"quat"</span>] <span class="hljs-comment"># (B, 4)</span> | |
| gripper_qpos = robot_state[<span class="hljs-string">"gripper"</span>][<span class="hljs-string">"qpos"</span>] <span class="hljs-comment"># (B, 2)</span> | |
| <span class="hljs-comment"># Convert quaternion to axis-angle</span> | |
| eef_axisangle = self._quat2axisangle(eef_quat) <span class="hljs-comment"># (B, 3)</span> | |
| <span class="hljs-comment"># Concatenate into single state vector</span> | |
| state = torch.cat((eef_pos, eef_axisangle, gripper_qpos), dim=-<span class="hljs-number">1</span>) | |
| state = state.<span class="hljs-built_in">float</span>() | |
| processed_obs[<span class="hljs-string">"observation.state"</span>] = state | |
| <span class="hljs-keyword">return</span> processed_obs<!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="why-these-transformations" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#why-these-transformations"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Why These Transformations?</span></h3> <ol data-svelte-h="svelte-1sxwv1m"><li><p><strong>Image Rotation</strong>: The HuggingFaceVLA/libero dataset has images rotated 180° from the raw LIBERO simulator. The processor handles this convention mismatch so policies trained on the dataset work seamlessly.</p></li> <li><p><strong>State Flattening</strong>: The raw LIBERO environment exposes nested dictionaries with all available state information (position, quaternion, velocity, matrix representation, etc.). The processor:</p> <ul><li>Selects the relevant components (pos, quat, gripper)</li> <li>Converts quaternion to axis-angle (more suitable for learning)</li> <li>Flattens to a single 8D vector that policies expect</li></ul></li> <li><p><strong>Flexibility</strong>: The environment still exposes <strong>all</strong> raw data. If you want to try different state representations (e.g., including velocities, using matrix representation instead of axis-angle), you can create a new processor without modifying the environment code.</p></li></ol> <h2 class="relative group"><a id="adding-environment-processors-for-new-environments" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#adding-environment-processors-for-new-environments"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Adding Environment Processors for New Environments</span></h2> <p data-svelte-h="svelte-3mpccp">To add environment processors for a new environment:</p> <h3 class="relative group"><a id="1-create-the-processor-step" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#1-create-the-processor-step"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>1. Create the Processor Step</span></h3> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-comment"># In src/lerobot/processor/env_processor.py</span> | |
| <span class="hljs-meta">@dataclass</span> | |
| <span class="hljs-meta">@ProcessorStepRegistry.register(<span class="hljs-params">name=<span class="hljs-string">"myenv_processor"</span></span>)</span> | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">MyEnvProcessorStep</span>(<span class="hljs-title class_ inherited__">ObservationProcessorStep</span>): | |
| <span class="hljs-string">"""Process observations from MyEnv."""</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">_process_observation</span>(<span class="hljs-params">self, observation</span>): | |
| processed = observation.copy() | |
| <span class="hljs-comment"># Your environment-specific transformations</span> | |
| <span class="hljs-keyword">if</span> <span class="hljs-string">"myenv.specific.state"</span> <span class="hljs-keyword">in</span> processed: | |
| state = processed.pop(<span class="hljs-string">"myenv.specific.state"</span>) | |
| <span class="hljs-comment"># Transform to standard format</span> | |
| processed[<span class="hljs-string">"observation.state"</span>] = self._transform_state(state) | |
| <span class="hljs-keyword">return</span> processed<!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="2-update-your-envconfig-subclass" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#2-update-your-envconfig-subclass"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>2. Update Your EnvConfig Subclass</span></h3> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-comment"># In src/lerobot/envs/factory.py</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">make_env_pre_post_processors</span>(<span class="hljs-params">env_cfg: EnvConfig</span>): | |
| <span class="hljs-keyword">if</span> <span class="hljs-built_in">isinstance</span>(env_cfg, LiberoEnv) <span class="hljs-keyword">or</span> <span class="hljs-string">"libero"</span> <span class="hljs-keyword">in</span> env_cfg.<span class="hljs-built_in">type</span>: | |
| preprocessor = PolicyProcessorPipeline(steps=[LiberoProcessorStep()]) | |
| <span class="hljs-keyword">elif</span> <span class="hljs-built_in">isinstance</span>(env_cfg, MyEnvConfig) <span class="hljs-keyword">or</span> <span class="hljs-string">"myenv"</span> <span class="hljs-keyword">in</span> env_cfg.<span class="hljs-built_in">type</span>: | |
| preprocessor = PolicyProcessorPipeline(steps=[MyEnvProcessorStep()]) | |
| <span class="hljs-keyword">else</span>: | |
| preprocessor = PolicyProcessorPipeline(steps=[]) | |
| postprocessor = PolicyProcessorPipeline(steps=[]) | |
| <span class="hljs-keyword">return</span> preprocessor, postprocessor<!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="3-use-in-evaluation" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#3-use-in-evaluation"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>3. Use in Evaluation</span></h3> <p data-svelte-h="svelte-1vf6x8d">No changes needed! The evaluation script automatically uses the appropriate processor:</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START -->lerobot-eval \ | |
| --policy.path=lerobot/my_policy \ | |
| --env.type=myenv \ <span class="hljs-comment"># Automatically uses MyEnvProcessorStep</span> | |
| --eval.n_episodes=10<!-- HTML_TAG_END --></pre></div> <h2 class="relative group"><a id="future-environment-postprocessors" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#future-environment-postprocessors"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Future: Environment Postprocessors</span></h2> <p data-svelte-h="svelte-1ggny72">Currently, postprocessors are identity (no-op) for all environments. Future use cases include:</p> <h3 class="relative group"><a id="action-space-transformations" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#action-space-transformations"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Action Space Transformations</span></h3> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-meta">@dataclass</span> | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">MyEnvActionPostprocessor</span>(<span class="hljs-title class_ inherited__">ProcessorStep</span>): | |
| <span class="hljs-string">"""Convert policy actions to environment-specific format."""</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">__call__</span>(<span class="hljs-params">self, transition: EnvTransition</span>) -> EnvTransition: | |
| action = transition[<span class="hljs-string">"action"</span>] | |
| <span class="hljs-comment"># Example: Convert from Cartesian to joint space</span> | |
| <span class="hljs-keyword">if</span> self.action_space == <span class="hljs-string">"joint"</span>: | |
| action = self.ik_solver(action) | |
| <span class="hljs-comment"># Example: Apply environment-specific safety limits</span> | |
| action = torch.clamp(action, self.min_action, self.max_action) | |
| transition[<span class="hljs-string">"action"</span>] = action | |
| <span class="hljs-keyword">return</span> transition<!-- HTML_TAG_END --></pre></div> <h3 class="relative group"><a id="coordinate-system-conversions" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#coordinate-system-conversions"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Coordinate System Conversions</span></h3> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg class="" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg> <div class="absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0"><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent; "></div> Copied</div></button></div> <pre class=""><!-- HTML_TAG_START --><span class="hljs-meta">@dataclass</span> | |
| <span class="hljs-keyword">class</span> <span class="hljs-title class_">CoordinateTransformPostprocessor</span>(<span class="hljs-title class_ inherited__">ProcessorStep</span>): | |
| <span class="hljs-string">"""Transform actions between coordinate systems."""</span> | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">__call__</span>(<span class="hljs-params">self, transition: EnvTransition</span>) -> EnvTransition: | |
| action = transition[<span class="hljs-string">"action"</span>] | |
| <span class="hljs-comment"># Example: Policy outputs in world frame, env expects base frame</span> | |
| action = self.world_to_base_transform(action) | |
| transition[<span class="hljs-string">"action"</span>] = action | |
| <span class="hljs-keyword">return</span> transition<!-- HTML_TAG_END --></pre></div> <h2 class="relative group"><a id="best-practices" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#best-practices"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Best Practices</span></h2> <ol data-svelte-h="svelte-1nsz6tw"><li><p><strong>Keep environment processors simple</strong>: They should only handle environment-specific data format issues, not complex learning-related transformations.</p></li> <li><p><strong>Use policy processors for model requirements</strong>: Normalization, batching, device placement, and tokenization belong in policy processors.</p></li> <li><p><strong>Expose all data from environments</strong>: Let processors decide what to use rather than hardcoding choices in the environment.</p></li> <li><p><strong>Document conventions</strong>: Clearly document any coordinate system conventions, camera orientations, or data formats that your processor handles.</p></li> <li><p><strong>Test independently</strong>: Environment processors should be testable without loading full policies or environments.</p></li></ol> <h2 class="relative group"><a id="summary" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#summary"><span><svg class="" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span></a> <span>Summary</span></h2> <p data-svelte-h="svelte-1cvtvxk">Environment processors provide a <strong>clean separation</strong> between environment-specific data transformations and policy-specific model requirements. This architecture:</p> <ul data-svelte-h="svelte-1cuerah"><li>✅ Enables easy experimentation with different state representations</li> <li>✅ Allows policies to work seamlessly across different environments</li> <li>✅ Keeps environment code focused on simulation/hardware interface</li> <li>✅ Makes processor pipelines more maintainable and debuggable</li> <li>✅ Follows the single responsibility principle</li></ul> <p data-svelte-h="svelte-sgldc8">The key insight: <strong>Environments define data formats, processors standardize them, policies consume standardized data.</strong> Each layer has a clear, focused responsibility.</p> <a class="!text-gray-400 !no-underline text-sm flex items-center not-prose mt-4" href="https://github.com/huggingface/lerobot/blob/main/docs/source/env_processor.mdx" target="_blank"><svg class="mr-1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M31,16l-7,7l-1.41-1.41L28.17,16l-5.58-5.59L24,9l7,7z"></path><path d="M1,16l7-7l1.41,1.41L3.83,16l5.58,5.59L8,23l-7-7z"></path><path d="M12.419,25.484L17.639,6.552l1.932,0.518L14.351,26.002z"></path></svg> <span data-svelte-h="svelte-zjs2n5"><span class="underline">Update</span> on GitHub</span></a> <p></p> | |
| <script> | |
| { | |
| __sveltekit_9kza6s = { | |
| assets: "/docs/lerobot/pr_3313/en", | |
| base: "/docs/lerobot/pr_3313/en", | |
| env: {} | |
| }; | |
| const element = document.currentScript.parentElement; | |
| const data = [null,null]; | |
| Promise.all([ | |
| import("/docs/lerobot/pr_3313/en/_app/immutable/entry/start.d3f1c0f3.js"), | |
| import("/docs/lerobot/pr_3313/en/_app/immutable/entry/app.04bb7687.js") | |
| ]).then(([kit, app]) => { | |
| kit.start(app, element, { | |
| node_ids: [0, 14], | |
| data, | |
| form: null, | |
| error: null | |
| }); | |
| }); | |
| } | |
| </script> | |
Xet Storage Details
- Size:
- 78.7 kB
- Xet hash:
- 3dbff3693e40b69123581688142ce58d943209978df263b23f48b925ad88bef8
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.