Python API
The modules and names other packages may import from rosetta (core) and
rosetta_ros (the ROS 2 robot interface). Each public module lists its names
in __all__. Every other module is internal and can change without notice.
test/test_public_api.py in each of the two packages pins the exact names.
Core modules
Core imports no robot middleware, so every module here imports without ROS.
Module |
Names |
Use |
|---|---|---|
|
|
Load and validate a contract. |
|
|
Runtime stream specs resolved from a |
|
|
Raised for any invalid contract. |
|
|
The contract file stored with a dataset ( |
|
|
Operator plugins for |
|
|
Codec plugins and the message to array boundary. |
|
|
The positional layout of stream specs within frame keys. |
|
|
|
|
|
The live robot as a framework adapter sees it. |
|
|
Framework adapter protocols and the registry that loads them by name. |
|
|
The robot interface protocol. |
|
|
Robot interfaces by name. |
The registries load plugins from the entry-point groups listed in Packages.
Protocols
FrameIO, from rosetta.frames.protocols:
Member |
Kind |
Behavior |
|---|---|---|
|
method |
Returns the current observation frame, |
|
property |
|
|
method |
Publishes one action frame, |
|
method |
Publishes the contract’s safety action. |
|
method |
Clears per-episode state such as buffers and warmup. |
DatasetWriter, from rosetta.policies. A writer is opened once, receives
one run of add_frame calls per episode, and is finalized once.
Member |
Behavior |
|---|---|
|
Translates the contract into the framework’s schema and opens the output. With |
|
Appends one frame. Besides the contract keys, a frame holds |
|
Flushes the buffered episode. |
|
Drops a partly buffered episode. Safe to call with nothing buffered. |
|
Writes top-level metadata and closes the dataset. Not called when every episode fails. |
PolicyRunner, from rosetta.policies:
Member |
Behavior |
|---|---|
|
Declares and reads settings on |
|
Blocks until |
|
Returns a |
|
Wakes a |
|
Releases framework resources. |
RunnerResult(success, message="") is a frozen dataclass. success is
True for a run that ended because it was asked to stop or because it
finished. policy_runner_node reports success=False as
termination_reason: error with message.
RunnerFeedback(queue_depth=0, published_actions=0) is a frozen dataclass.
Both counters must stay non-negative. policy_runner_node carries them as
uint32.
RunnerHost:
Member |
Behavior |
|---|---|
|
Declares a setting, or does nothing when |
|
The setting’s current value. |
|
Property. A logger with |
RobotInterface, from rosetta.robots.protocols:
Member |
Behavior |
|---|---|
|
Imports the interface’s built-in codecs. Called once per process for every installed interface, before |
|
Returns the |
|
Raises |
The loaders instantiate each plugin class with no arguments and check it
against its protocol. An unknown name raises ValueError listing the
installed names. A class missing a protocol method raises TypeError naming
the missing methods.
ROS 2 modules
The node toolkit that rosetta_ros_hil and the LeRobot plugins build on.
Module |
Names |
Use |
Imports ROS |
|---|---|---|---|
|
|
Base classes for lifecycle nodes. See Lifecycle nodes. |
yes |
|
|
The termination reasons, taken from the |
yes |
|
|
Send and cancel goals on other action servers from inside a node’s own work. Both block the calling thread. |
yes |
|
|
The ROS 2 |
yes |
|
|
Runs a node on a private rclpy context with its own executor thread, for processes Rosetta does not own. |
yes |
|
|
A |
yes |
|
|
|
yes |
|
|
Helpers for launch files. |
yes |
|
|
Read and write message fields by dotted path. |
no |
LeRobot packages
These names are each package’s __all__. No test pins them.
Module |
Names |
|---|---|
|
|
|
|
|
|
Lifecycle nodes
Base classes for lifecycle nodes, from rosetta_ros.rosetta_lifecycle_node.
RosettaLifecycleNode
RosettaLifecycleNode is the base class of episode_recorder_node,
policy_runner_node and hil_manager_node. It owns the lifecycle
transitions and a single work slot, so a node built on it runs one piece of
work at a time and stops it on deactivate.
Member |
Kind |
Behavior |
|---|---|---|
|
override |
Creates resources on configure. Raising fails the transition, and the base logs the traceback and tears down. |
|
override |
Destroys what |
|
optional override |
Wakes work blocked in I/O after a stop. Must be safe with no work active. |
|
optional override |
Secures hardware after work stops. |
|
action callbacks |
Pass to the |
|
context manager |
Yields the stop event and releases the work slot on every exit. |
|
method |
Stops the current work and records why. The first reason wins. |
|
properties |
The recorded reason, or |
|
method |
Claims the slot and runs |
|
method |
Cancels the current work for a |
|
method |
Forwards a cancel to the node’s own action server, so the goal ends |
|
method |
Claims the work slot. Returns |
|
method |
Publishes status or result from a work thread, and logs instead of raising when the node is already torn down. |
|
properties |
Work in progress, and the lifecycle state. |
|
class attribute |
Seconds deactivate waits for work to stop before sending the safety action anyway. |
Subclasses never override on_configure, on_deactivate or the other
lifecycle callbacks. Deactivate closes the work slot, stops the current work
with reason node_deactivated, waits up to STOP_WORK_TIMEOUT_SEC, then
calls send_safety_action(). Cleanup is refused while work is in progress.
BridgeLifecycleNode
BridgeLifecycleNode(node_name, observation_specs, action_specs, fps) adds a
TopicBridge as self.bridge, set up and torn down with the node, and sends
the bridge’s safety action. The LeRobot robot and teleoperator plugins use it.
Example
This node serves the RunPolicy action as wait. Each goal waits until it is
cancelled or max_duration_s passes.
from rclpy.action import ActionServer
from rclpy.callback_groups import ReentrantCallbackGroup
from rosetta_ros.node_utils import TERMINATION_COMPLETED, finish_goal, spin_lifecycle_node
from rosetta_ros.rosetta_lifecycle_node import RosettaLifecycleNode
from rosetta_interfaces.action import RunPolicy
class WaitNode(RosettaLifecycleNode):
"""Runs one goal at a time, until cancelled or for max_duration_s."""
def __init__(self, **kwargs):
super().__init__("wait_node", **kwargs)
self._server = None
def setup(self):
self._server = ActionServer(
self,
RunPolicy,
"wait",
execute_callback=self.execute,
goal_callback=self.on_goal,
cancel_callback=self.on_cancel,
callback_group=ReentrantCallbackGroup(),
)
def teardown(self):
if self._server is not None:
self._server.destroy()
self._server = None
def execute(self, goal_handle):
result = RunPolicy.Result()
with self.goal_work(goal_handle) as stop_event:
stopped = stop_event.wait(goal_handle.request.max_duration_s or None)
result.termination_reason = self.stop_reason if stopped else TERMINATION_COMPLETED
finish_goal(goal_handle, result)
return result
def main():
return spin_lifecycle_node(WaitNode)
if __name__ == "__main__":
main()
After ros2 lifecycle set /wait_node configure and activate, a goal with
max_duration_s: 1.0 ends SUCCEEDED with termination_reason: completed,
and a cancelled goal ends CANCELED with termination_reason: cancelled. The
reentrant callback group lets the cancel callback run while execute blocks.