BaseDriver Interface Overview
After implementing the following methods, Watchdog can use your driver just like a built-in one. It is recommended to implement the minimal interface first and ensure Watchdog can load it properly.
class BaseDriver(ABC):
def get_profile_path(self) -> Path: ...
def load_scene(self, scene: dict[str, dict]) -> None: ...
def execute_action(self, action_type: str, params: dict) -> str: ...
def get_scene(self) -> dict[str, dict]: ...
# Common optional methods
def connect(self) -> bool: ...
def disconnect(self) -> None: ...
def is_connected(self) -> bool: ...
def health_check(self) -> bool: ...
def get_runtime_state(self) -> dict[str, Any]: ...
Returns the path to the EMBODIED.md profile
Initialize internal state from ENVIRONMENT.md
Execute an action and return a human-readable result
Return current environment state for writeback to ENVIRONMENT.md
Implement a Minimal Loadable Version First
It is recommended to first ensure that Watchdog can properly import and instantiate the Driver, and complete a full action consumption cycle, before gradually extending functionality.
from pathlib import Path
from hal.base_driver import BaseDriver
class MyRobotDriver(BaseDriver):
def __init__(self, gui: bool = False, **kwargs):
self._scene = {}
def get_profile_path(self) -> Path:
return Path(__file__).resolve().parent / "profiles" / "my_robot.md"
def load_scene(self, scene: dict[str, dict]) -> None:
self._scene = dict(scene)
def execute_action(self, action_type: str, params: dict) -> str:
return f"executed {action_type}"
def get_scene(self) -> dict[str, dict]:
return dict(self._scene)
Supplement the Profile File
What Goes in the Profile
- Identity: name, type, driver/profile
- Sensors / Degrees of Freedom
- Supported Actions
- Physical Constraints
- Connection & Runtime Protocol
Impact of Missing Profile
The Critic has no basis for action constraints, and ROBOTS.md can't provide reliable capability summaries. The Agent won't know what to assign to this robot.
Built-in Driver Registration Method
For built-in drivers (not external plugins), you also need to add a short-name mapping in the registry.
DRIVER_REGISTRY: dict[str, str] = {
"simulation": "hal.drivers.simulation_driver.SimulationDriver",
"go2_edu": "hal.drivers.go2_driver.Go2Driver",
"my_robot": "hal.drivers.my_robot_driver.MyRobotDriver",
}
External plugins are discovered through their plugin manifest and registry — no need to modify this line.
Watchdog Actual Invocation Sequence
Can import and instantiate
get_profile_path() returns a valid path
connect() / health_check() working
Action type and parameters can be handled
get_scene() / get_runtime_state() serialize correctly
Debugging Sequence
In a Python shell: from hal.drivers.my_robot_driver import MyRobotDriver; d = MyRobotDriver() — no errors
Check startup logs or verify the correct EMBODIED.md was generated in the workspace
Add logging output to the method to confirm it is being called correctly
After executing an action, cat ENVIRONMENT.md to check if robot state was updated
Trigger with a simple, clear instruction and observe ACTION.md generation and execution results