precommit style nit

This commit is contained in:
Michel Aractingi
2025-08-06 17:44:32 +02:00
committed by Adil Zouitine
parent 8d5f519fcb
commit feb3fed5e8
+10 -2
View File
@@ -21,7 +21,7 @@ processed_image = processor(transition)["observation"]["observation.image"] # V
``` ```
On the other hand, when a model returns a certain action to be executed on the robot, it is often that one has to post-process this action to make it compatible to run on the robot. On the other hand, when a model returns a certain action to be executed on the robot, it is often that one has to post-process this action to make it compatible to run on the robot.
For example, the model might return joint positions values that range from `[-1, 1]` and one would need to scale them to the ranges of the minumum and maximum joint angle positions of the robot. For example, the model might return joint positions values that range from `[-1, 1]` and one would need to scale them to the ranges of the minimum and maximum joint angle positions of the robot.
For instance, in LeRobot's `UnnormalizerProcessor`, model outputs are in the normalized range `[-1, 1]` and need to be converted back to actual robot joint ranges: For instance, in LeRobot's `UnnormalizerProcessor`, model outputs are in the normalized range `[-1, 1]` and need to be converted back to actual robot joint ranges:
@@ -36,12 +36,13 @@ real_action = unnormalizer(transition)["action"]
``` ```
The unnormalizer uses the dataset statistics to convert back: The unnormalizer uses the dataset statistics to convert back:
```python ```python
# For MIN_MAX normalization: action = (normalized + 1) * (max - min) / 2 + min # For MIN_MAX normalization: action = (normalized + 1) * (max - min) / 2 + min
real_action = (normalized_action + 1) * (max_val - min_val) / 2 + min_val real_action = (normalized_action + 1) * (max_val - min_val) / 2 + min_val
``` ```
All this situation point us towards the need for a mechanism to preprocess the data before inputed to the policies and then post-process the action that are returend to be executed on the robot. All this situation point us towards the need for a mechanism to preprocess the data before being passed to the policies and then post-process the action that are returned to be executed on the robot.
To that end, LeRobot provides a pipeline mechanism to implement a sequence of processing steps for the input data and the output action. To that end, LeRobot provides a pipeline mechanism to implement a sequence of processing steps for the input data and the output action.
@@ -113,15 +114,18 @@ class ImageProcessor:
``` ```
Key principles for implementing `__call__`: Key principles for implementing `__call__`:
- Always check if the required data exists (observations, actions, etc.) - Always check if the required data exists (observations, actions, etc.)
- Return the original transition unchanged if no processing is needed - Return the original transition unchanged if no processing is needed
- Create a copy of the transition to avoid side effects - Create a copy of the transition to avoid side effects
- Only modify the specific keys your processor is responsible for - Only modify the specific keys your processor is responsible for
### Configuration and State Management ### Configuration and State Management
LeRobot processors support serialization and deserialization through three key methods. Here's how they work using `NormalizerProcessor` as an example: LeRobot processors support serialization and deserialization through three key methods. Here's how they work using `NormalizerProcessor` as an example:
#### `get_config()` - Serializable Configuration #### `get_config()` - Serializable Configuration
This method returns all non-tensor configuration that can be saved to JSON: This method returns all non-tensor configuration that can be saved to JSON:
```python ```python
@@ -144,6 +148,7 @@ class NormalizerProcessor:
``` ```
#### `state_dict()` - Tensor State #### `state_dict()` - Tensor State
This method returns only PyTorch tensors that need special serialization: This method returns only PyTorch tensors that need special serialization:
```python ```python
@@ -157,6 +162,7 @@ def state_dict(self) -> dict[str, torch.Tensor]:
``` ```
#### `load_state_dict()` - Restore Tensor State #### `load_state_dict()` - Restore Tensor State
This method restores the tensor state from a saved state dictionary: This method restores the tensor state from a saved state dictionary:
```python ```python
@@ -173,6 +179,7 @@ def load_state_dict(self, state: dict[str, torch.Tensor]) -> None:
``` ```
#### Usage Example #### Usage Example
```python ```python
# Save processor # Save processor
config = processor.get_config() config = processor.get_config()
@@ -236,6 +243,7 @@ def feature_contract(self, features: dict[str, PolicyFeature]) -> dict[str, Poli
``` ```
**Key principles:** **Key principles:**
- Use `features.pop(old_key)` to remove the old feature and get its value - Use `features.pop(old_key)` to remove the old feature and get its value
- Use `features[new_key] = old_feature` to add the new feature with same properties - Use `features[new_key] = old_feature` to add the new feature with same properties
- Always return the modified features dictionary - Always return the modified features dictionary