Download fact/runtime_stats.py from zhicao/FACT: direct link, hf CLI and curl.
- Browser
- Download file 4 kB
-
https://huggingface.co/zhicao/FACT/resolve/main/fact/runtime_stats.py
- Command line
-
hf download hf://zhicao/FACT/fact/runtime_stats.py
-
curl -L -o runtime_stats.py https://huggingface.co/zhicao/FACT/resolve/main/fact/runtime_stats.py
4 kB
| """Dataset normalisation statistics and delta-base inversion for online execution.""" | |
| from __future__ import annotations | |
| import json | |
| from dataclasses import dataclass | |
| from pathlib import Path | |
| import numpy as np | |
| from .data_utils import matrix_to_rotation_6d as _matrix_to_rotation_6d | |
| from .data_utils import rotation_6d_to_matrix | |
| def delta_base_to_absolute( | |
| reference_state: np.ndarray, delta_base_action: np.ndarray | |
| ) -> np.ndarray: | |
| """Invert T-Rex delta-base arm poses; hand targets are already absolute.""" | |
| reference = np.asarray(reference_state, dtype=np.float64) | |
| delta = np.asarray(delta_base_action, dtype=np.float64) | |
| if reference.shape != (62,) or delta.shape[-1] != 62: | |
| raise ValueError("expected reference [62] and delta action [...,62]") | |
| output = np.empty_like(delta) | |
| for pose_slice, hand_slice in ( | |
| (slice(0, 9), slice(9, 31)), | |
| (slice(31, 40), slice(40, 62)), | |
| ): | |
| reference_pose = reference[pose_slice] | |
| delta_pose = delta[..., pose_slice] | |
| reference_rotation = rotation_6d_to_matrix(reference_pose[3:9]) | |
| delta_rotation = rotation_6d_to_matrix(delta_pose[..., 3:9]) | |
| target_translation = ( | |
| reference_pose[:3] | |
| + np.einsum("ij,...j->...i", reference_rotation, delta_pose[..., :3]) | |
| ) | |
| target_rotation = np.einsum( | |
| "ij,...jk->...ik", reference_rotation, delta_rotation | |
| ) | |
| output[..., pose_slice] = np.concatenate( | |
| (target_translation, _matrix_to_rotation_6d(target_rotation)), axis=-1 | |
| ) | |
| output[..., hand_slice] = delta[..., hand_slice] | |
| return output.astype(np.float32) | |
| class TrexRuntimeStatistics: | |
| action_q01: np.ndarray | |
| action_q99: np.ndarray | |
| state_q01: np.ndarray | |
| state_q99: np.ndarray | |
| force_q01: np.ndarray | |
| force_q99: np.ndarray | |
| def from_dataset(cls, dataset_root: str | Path) -> "TrexRuntimeStatistics": | |
| root = Path(dataset_root) | |
| with (root / "meta" / "relative_stats_dreamzero.json").open() as handle: | |
| action = json.load(handle)["eef62"] | |
| with (root / "meta" / "stats.json").open() as handle: | |
| stats = json.load(handle) | |
| force = stats["observation.tactile_force"] | |
| state = stats["observation.state_eef62"] | |
| return cls( | |
| action_q01=np.asarray(action["q01"], dtype=np.float32), | |
| action_q99=np.asarray(action["q99"], dtype=np.float32), | |
| state_q01=np.asarray(state["q01"], dtype=np.float32), | |
| state_q99=np.asarray(state["q99"], dtype=np.float32), | |
| force_q01=np.asarray(force["q01"], dtype=np.float32).reshape(10, 6), | |
| force_q99=np.asarray(force["q99"], dtype=np.float32).reshape(10, 6), | |
| ) | |
| def normalize_force(self, force: np.ndarray) -> np.ndarray: | |
| values = np.asarray(force, dtype=np.float32) | |
| scale = self.force_q99 - self.force_q01 | |
| normalized = np.where( | |
| scale != 0, | |
| 2.0 * (values - self.force_q01) / np.where(scale == 0, 1.0, scale) | |
| - 1.0, | |
| values, | |
| ) | |
| return np.clip(normalized, -1.0, 1.0).astype(np.float32) | |
| def normalize_state(self, state: np.ndarray) -> np.ndarray: | |
| values = np.asarray(state, dtype=np.float32) | |
| scale = self.state_q99 - self.state_q01 | |
| normalized = np.where( | |
| scale != 0, | |
| 2.0 * (values - self.state_q01) / np.where(scale == 0, 1.0, scale) | |
| - 1.0, | |
| values, | |
| ) | |
| return np.clip(normalized, -1.0, 1.0).astype(np.float32) | |
| def denormalize_action(self, normalized_action: np.ndarray) -> np.ndarray: | |
| values = np.asarray(normalized_action, dtype=np.float32)[..., :62] | |
| return ( | |
| (values + 1.0) * 0.5 * (self.action_q99 - self.action_q01) | |
| + self.action_q01 | |
| ).astype(np.float32) | |
| __all__ = ["TrexRuntimeStatistics", "delta_base_to_absolute"] | |