2026-06-02 15:40:16 +00:00
|
|
|
from enum import StrEnum
|
|
|
|
|
|
|
|
|
|
|
2026-05-26 16:23:04 +00:00
|
|
|
CONTROLLER_SCHEMA_VERSION = "controller-job.v1"
|
|
|
|
|
RUN_LOG_SCHEMA_VERSION = "run-log.v1"
|
|
|
|
|
MANUAL_SESSION_SCHEMA_VERSION = "manual-session-log.v1"
|
|
|
|
|
MACHINE_CAPABILITIES_SCHEMA_VERSION = "machine-capabilities.v1"
|
|
|
|
|
MACHINE_ID = "fullum-alpha"
|
|
|
|
|
CONTROLLER_VERSION_PREFIX = "polisher-control/"
|
2026-06-02 15:40:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class SpindleDirection(StrEnum):
|
|
|
|
|
"""Toolhead spindle rotation direction using stable protocol/schema values.
|
|
|
|
|
|
|
|
|
|
Physical convention: clockwise/counter-clockwise are as viewed from above the
|
|
|
|
|
toolhead looking down toward the mirror/tool contact. ODrive sign mapping is
|
|
|
|
|
a commissioning item and must be configured so these UI/protocol values match
|
|
|
|
|
the observed tool rotation.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
CLOCKWISE = "cw"
|
|
|
|
|
COUNTER_CLOCKWISE = "ccw"
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def allowed_values(cls) -> list[str]:
|
|
|
|
|
return [direction.value for direction in cls]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_SPINDLE_DIRECTION_ALIASES = {
|
|
|
|
|
"cw": SpindleDirection.CLOCKWISE,
|
|
|
|
|
"clockwise": SpindleDirection.CLOCKWISE,
|
|
|
|
|
"c.w.": SpindleDirection.CLOCKWISE,
|
|
|
|
|
"ccw": SpindleDirection.COUNTER_CLOCKWISE,
|
|
|
|
|
"counterclockwise": SpindleDirection.COUNTER_CLOCKWISE,
|
|
|
|
|
"counter-clockwise": SpindleDirection.COUNTER_CLOCKWISE,
|
|
|
|
|
"counter_clockwise": SpindleDirection.COUNTER_CLOCKWISE,
|
|
|
|
|
"anticlockwise": SpindleDirection.COUNTER_CLOCKWISE,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def normalize_spindle_direction(value: str | SpindleDirection) -> SpindleDirection:
|
|
|
|
|
"""Normalize UI/protocol aliases to a SpindleDirection enum."""
|
|
|
|
|
if isinstance(value, SpindleDirection):
|
|
|
|
|
return value
|
|
|
|
|
key = value.strip().lower()
|
|
|
|
|
try:
|
|
|
|
|
return _SPINDLE_DIRECTION_ALIASES[key]
|
|
|
|
|
except KeyError as exc:
|
|
|
|
|
allowed = ", ".join(SpindleDirection.allowed_values())
|
|
|
|
|
raise ValueError(f"Unsupported spindle direction {value!r}; expected one of: {allowed}") from exc
|