Source code for embodichain_benchmarks.motion_generation.registry

# ----------------------------------------------------------------------------
# Copyright (c) 2021-2026 DexForce Technology Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------

"""Planner and scenario registries used by the generic benchmark runner."""

from __future__ import annotations

from collections.abc import Mapping
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from .config import PlannerSpecCfg, RobotSpecCfg
    from .planners.base import PlannerAdapter, PlannerContext
    from .robots.base import RobotProvider
    from .scenarios.base import ScenarioProvider

__all__ = [
    "create_planner_adapter",
    "create_scenario_provider",
    "create_robot_provider",
    "planner_adapter_names",
    "register_planner_adapter",
    "register_scenario_provider",
    "register_robot_provider",
    "robot_provider_names",
    "scenario_provider_names",
    "unregister_planner_adapter",
]

_PLANNER_ADAPTERS: dict[str, type["PlannerAdapter"]] = {}
_SCENARIO_PROVIDERS: dict[str, type["ScenarioProvider"]] = {}
_ROBOT_PROVIDERS: dict[str, type["RobotProvider"]] = {}


[docs] def register_planner_adapter(name: str, adapter_cls: type["PlannerAdapter"]) -> None: """Register one adapter class under a stable configuration name.""" if not name: raise ValueError("Planner adapter name must not be empty.") previous = _PLANNER_ADAPTERS.get(name) if previous is not None and previous is not adapter_cls: raise ValueError(f"Planner adapter {name!r} is already registered.") _PLANNER_ADAPTERS[name] = adapter_cls
[docs] def unregister_planner_adapter(name: str) -> None: """Remove one planner adapter registration when present.""" _PLANNER_ADAPTERS.pop(name, None)
[docs] def planner_adapter_names() -> tuple[str, ...]: """Return registered adapter names in deterministic order.""" return tuple(sorted(_PLANNER_ADAPTERS))
[docs] def create_planner_adapter( spec: "PlannerSpecCfg", context: "PlannerContext", *, adapters: Mapping[str, type[PlannerAdapter]] | None = None, ) -> "PlannerAdapter": """Construct an adapter, preferring the current run's explicit mapping. Args: spec: Algorithm identity and backend configuration. context: Robot and shared evaluation budgets. adapters: Overrides local to this run. The global registry is unchanged. Returns: A new adapter owned by the caller. """ if adapters is not None and spec.adapter in adapters: return adapters[spec.adapter](spec=spec, context=context) try: adapter_cls = _PLANNER_ADAPTERS[spec.adapter] except KeyError as exc: raise ValueError( f"Unknown planner adapter {spec.adapter!r}; " f"registered adapters: {planner_adapter_names()}." ) from exc return adapter_cls(spec=spec, context=context)
[docs] def register_robot_provider(name: str, provider_cls: type["RobotProvider"]) -> None: """Register one robot provider under a stable suite name.""" if not name: raise ValueError("Robot provider name must not be empty.") previous = _ROBOT_PROVIDERS.get(name) if previous is not None and previous is not provider_cls: raise ValueError(f"Robot provider {name!r} is already registered.") _ROBOT_PROVIDERS[name] = provider_cls
[docs] def robot_provider_names() -> tuple[str, ...]: """Return registered robot-provider names in deterministic order.""" return tuple(sorted(_ROBOT_PROVIDERS))
[docs] def create_robot_provider(spec: "RobotSpecCfg") -> "RobotProvider": """Construct the robot provider selected by a suite.""" try: provider_cls = _ROBOT_PROVIDERS[spec.provider] except KeyError as exc: raise ValueError( f"Unknown robot provider {spec.provider!r}; " f"registered providers: {robot_provider_names()}." ) from exc return provider_cls(spec)
[docs] def register_scenario_provider( name: str, provider_cls: type["ScenarioProvider"] ) -> None: """Register one scenario provider class under a stable configuration name.""" if not name: raise ValueError("Scenario provider name must not be empty.") previous = _SCENARIO_PROVIDERS.get(name) if previous is not None and previous is not provider_cls: raise ValueError(f"Scenario provider {name!r} is already registered.") _SCENARIO_PROVIDERS[name] = provider_cls
[docs] def scenario_provider_names() -> tuple[str, ...]: """Return registered scenario provider names in deterministic order.""" return tuple(sorted(_SCENARIO_PROVIDERS))
[docs] def create_scenario_provider(name: str) -> "ScenarioProvider": """Construct the scenario provider selected by a track specification.""" try: provider_cls = _SCENARIO_PROVIDERS[name] except KeyError as exc: raise ValueError( f"Unknown scenario provider {name!r}; " f"registered providers: {scenario_provider_names()}." ) from exc return provider_cls()