mirror of
https://github.com/huggingface/lerobot.git
synced 2026-05-25 05:29:55 +00:00
precommit style nit
This commit is contained in:
committed by
Adil Zouitine
parent
8d5f519fcb
commit
feb3fed5e8
@@ -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.
|
||||
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:
|
||||
|
||||
@@ -36,12 +36,13 @@ real_action = unnormalizer(transition)["action"]
|
||||
```
|
||||
|
||||
The unnormalizer uses the dataset statistics to convert back:
|
||||
|
||||
```python
|
||||
# For MIN_MAX normalization: action = (normalized + 1) * (max - min) / 2 + min
|
||||
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.
|
||||
|
||||
@@ -113,15 +114,18 @@ class ImageProcessor:
|
||||
```
|
||||
|
||||
Key principles for implementing `__call__`:
|
||||
|
||||
- Always check if the required data exists (observations, actions, etc.)
|
||||
- Return the original transition unchanged if no processing is needed
|
||||
- Create a copy of the transition to avoid side effects
|
||||
- Only modify the specific keys your processor is responsible for
|
||||
|
||||
### Configuration and State Management
|
||||
|
||||
LeRobot processors support serialization and deserialization through three key methods. Here's how they work using `NormalizerProcessor` as an example:
|
||||
|
||||
#### `get_config()` - Serializable Configuration
|
||||
|
||||
This method returns all non-tensor configuration that can be saved to JSON:
|
||||
|
||||
```python
|
||||
@@ -144,6 +148,7 @@ class NormalizerProcessor:
|
||||
```
|
||||
|
||||
#### `state_dict()` - Tensor State
|
||||
|
||||
This method returns only PyTorch tensors that need special serialization:
|
||||
|
||||
```python
|
||||
@@ -157,6 +162,7 @@ def state_dict(self) -> dict[str, torch.Tensor]:
|
||||
```
|
||||
|
||||
#### `load_state_dict()` - Restore Tensor State
|
||||
|
||||
This method restores the tensor state from a saved state dictionary:
|
||||
|
||||
```python
|
||||
@@ -173,6 +179,7 @@ def load_state_dict(self, state: dict[str, torch.Tensor]) -> None:
|
||||
```
|
||||
|
||||
#### Usage Example
|
||||
|
||||
```python
|
||||
# Save processor
|
||||
config = processor.get_config()
|
||||
@@ -236,6 +243,7 @@ def feature_contract(self, features: dict[str, PolicyFeature]) -> dict[str, Poli
|
||||
```
|
||||
|
||||
**Key principles:**
|
||||
|
||||
- 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
|
||||
- Always return the modified features dictionary
|
||||
|
||||
Reference in New Issue
Block a user