49 lines
1.7 KiB
Python
49 lines
1.7 KiB
Python
"""Per-session sensor value overrides (replacement and/or offset)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
class SensorEditor:
|
|
def __init__(self) -> None:
|
|
self._replacements: dict[int, float] = {}
|
|
self._offsets: dict[int, float] = {}
|
|
|
|
|
|
def set_replacement(self, index: int, value: float) -> None:
|
|
"""Force sensor `index` to read `value` for every frame this session."""
|
|
self._replacements[index] = value
|
|
|
|
def set_offset(self, index: int, value: float) -> None:
|
|
"""Shift sensor `index` by `delta` (applied after any replacement)."""
|
|
self._offsets[index] = value
|
|
|
|
def clear(self, index: int | None = None) -> None:
|
|
"""Remove overrides. Pass an index to clear one sensor; omit to clear all."""
|
|
if index is None:
|
|
self._replacements.clear()
|
|
self._offsets.clear()
|
|
else:
|
|
self._replacements.pop(index, None)
|
|
self._offsets.pop(index, None)
|
|
def has_overrides(self) -> bool:
|
|
return bool(self._replacements or self._offsets)
|
|
|
|
def active_indices(self) -> list[int]:
|
|
"""Return sorted sensor indices that have any override."""
|
|
return sorted(set(self._replacements) | set(self._offsets))
|
|
|
|
|
|
def apply(self, values: list[float]) -> list[float]:
|
|
"""Return a new list wit all overrides applied (original unchanged)"""
|
|
if not self.has_overrides():
|
|
return list(values)
|
|
result = list(values)
|
|
for i in range(len(result)):
|
|
v = result[i]
|
|
if i in self._replacements:
|
|
v = self._replacements[i]
|
|
if i in self._offsets:
|
|
v += self._offsets[i]
|
|
result[i] = v
|
|
return result
|