API Reference
Core Classes
LuckyRobots
LuckyEngineClient
- class luckyrobots.LuckyEngineClient(host: str = '127.0.0.1', port: int = 50051, timeout: float = 5.0, *, robot_name: str | None = None)[source]
Client for connecting to the LuckyEngine gRPC server.
Provides access to gRPC services for RL training: - AgentService: stepping, resets - SceneService: simulation mode control - MujocoService: health checks, joint state
- Usage:
client = LuckyEngineClient(host=”127.0.0.1”, port=50051) client.connect() client.wait_for_server()
schema = client.get_agent_schema() obs = client.step(actions=[0.0] * 12)
client.close()
- __init__(host: str = '127.0.0.1', port: int = 50051, timeout: float = 5.0, *, robot_name: str | None = None) None[source]
Initialize the LuckyEngine gRPC client.
- Parameters:
host – gRPC server host address.
port – gRPC server port.
timeout – Default timeout for RPC calls in seconds.
robot_name – Default robot name for calls that require it.
- connect() None[source]
Connect to the LuckyEngine gRPC server.
Opens the gRPC channel. Service stubs are created lazily on first access so importers can skip unused services without cost.
- Raises:
GrpcConnectionError – If connection fails.
- health_check(timeout: float | None = None) bool[source]
Perform a health check by calling GetMujocoInfo.
- Parameters:
timeout – Timeout in seconds (uses default if None).
- Returns:
True if server responds, False otherwise.
- wait_for_server(timeout: float = 30.0, poll_interval: float = 0.5) bool[source]
Wait for the gRPC server to become available.
- Parameters:
timeout – Maximum time to wait in seconds.
poll_interval – Time between connection attempts.
- Returns:
True if server became available, False if timeout.
- property pb: Any
Access protobuf modules grouped by domain (e.g., client.pb.scene).
- property robot_name: str | None
Default robot name used by calls that accept an optional robot_name.
- set_robot_name(robot_name: str) None[source]
Set the default robot name used by calls that accept an optional robot_name.
- property channel: Channel
The underlying gRPC channel.
Exposed so users can attach their own service stubs using the same connection (shared keep-alive, auth, etc.):
client.connect() my_stub = my_pb2_grpc.MyServiceStub(client.channel)
- property scene: Any
SceneService stub (lazy).
- property mujoco: Any
MujocoService stub (lazy) — agent-scoped joint state.
For the full, engine-wide MuJoCo model (every joint, every actuator), use
mujoco_sceneinstead.
- property mujoco_scene: Any
MujocoSceneService stub (lazy) — engine-wide MuJoCo access.
Exposes every joint, actuator, and the full qpos/qvel/ctrl vectors in the loaded model. Use the higher-level helpers
get_model_info(),get_full_state(), andset_ctrl()for common operations.
- property agent: Any
AgentService stub (lazy).
- property debug: Any
DebugService stub (lazy).
- property camera: Any
CameraService stub (lazy).
- property telemetry: Any
TelemetryService stub (lazy) — lightweight qpos + ctrl streaming.
- property viewport: Any
ViewportService stub (lazy) — editor viewport pixel streaming.
- property lidar: Any
LidarService stub (lazy) — material-aware lidar scans for training clients.
- register_stub(name: str, stub_class: Any) Any[source]
Attach a third-party stub class to this client’s channel.
Useful when an engine build exposes a service that the shipped SDK doesn’t know about:
client.register_stub(“my_svc”, my_pb2_grpc.MyServiceStub) client.my_svc.DoThing(…)
- Parameters:
name – Attribute name under which the stub is exposed.
stub_class – Generated
*Stubclass from a_pb2_grpcmodule.
- Returns:
The instantiated stub (also available as
client.<name>).
- discover_services() list[str][source]
Ask the server which gRPC services it advertises.
Uses
grpc.reflection.v1alpha.ServerReflection. Requires the engine to be built with reflection enabled (default in the v0.2.0+ LuckyEngine server). The standard reflection service itself is filtered out of the result.
- configure_cameras(cameras: list[dict]) None[source]
Configure cameras to capture on every Step RPC.
- Parameters:
cameras –
List of camera configs. Each dict has keys: name: Camera entity name in the scene. width: Desired image width (0 = native resolution). height: Desired image height (0 = native resolution). kind: “color” (default) or “depth”. Depth frames carry live
metric depth packed as gray16le; convert to metres with metres = code * depth_scale. Requires a camera configured for depth capture.
format: “raw” (default) or “jpeg” (color only).
- set_lidar_live(live: bool = True, timeout: float | None = None)[source]
Keep the lidar firing every step, even when you’re not recording.
Call this once before polling scans with get_lidar_scan(); the setting persists across resets. Like the other scene-inspection calls (list_cameras, get_full_state, …), run it while the simulation is idle — not from inside an active step() loop.
- get_lidar_scan(sensor: int = 0, material: bool = False, want_secondary: bool = False, timeout: float | None = None)[source]
Read a lidar scan for the given sensor index (0-based).
Returns a LidarScanResponse:
beams(channels * azimuth_bins),ranges(metres per beam,-1.0= no return), andsecondary_rangeswhenwant_secondary. Callset_lidar_live(True)once first, then read scans while the simulation is idle — like the other scene-inspection calls, not from inside an active step() loop.
- get_lidar_beam_count(sensor: int = 0, timeout: float | None = None) int[source]
Number of beams (channels * azimuth_bins) for the given lidar sensor.
- list_cameras(timeout: float | None = None) list[dict][source]
List available cameras in the scene.
- Returns:
List of dicts with ‘name’ and ‘id’ keys for each camera.
- set_action_group(group_name: str, actions: list[float], action_indices: list[int], agent_name: str = '', timeout: float | None = None) bool[source]
Preload actions for a named group without triggering a physics step.
Call this for each policy/controller, then call step() to fire them all atomically in one physics tick.
- Parameters:
group_name – Name for this action group (e.g., “lower_body”, “right_arm”).
actions – Action values for this group.
action_indices – Which indices in the action vector these map to.
agent_name – Agent name (empty = default agent).
timeout – RPC timeout in seconds.
- Returns:
True if the group was preloaded successfully.
- get_joint_state(robot_name: str = '', timeout: float | None = None)[source]
Get current joint state (positions and velocities).
- Parameters:
robot_name – Robot entity name (uses default if empty).
timeout – RPC timeout in seconds.
- Returns:
GetJointStateResponse with state.positions (qpos) and state.velocities (qvel).
- get_mujoco_info(robot_name: str = '', timeout: float | None = None)[source]
Get MuJoCo model information (joint names, limits, etc.).
- get_model_info(timeout: float | None = None)[source]
Introspect the full loaded MuJoCo model.
Returns a
GetModelInfoResponsewhosejointsandactuatorslists cover every entry inmjModel— not just those declared by the registered RL agent. Use this to discover fingers, non-agent joints, and actuator names the agent API doesn’t expose.
- get_full_state(*, include_qpos: bool = True, include_qvel: bool = True, include_ctrl: bool = True, timeout: float | None = None)[source]
Snapshot the complete mjData state (qpos, qvel, ctrl, time).
- stream_full_state(*, target_fps: int = 30, include_qpos: bool = True, include_qvel: bool = True, include_ctrl: bool = True)[source]
Iterate
GetFullStateResponsemessages at approximatelytarget_fps.Example
- for resp in client.stream_full_state(target_fps=60):
qpos = list(resp.state.qpos)
- set_ctrl(values: Any, *, skip_range_clamp: bool = False, wait_for_next_step: bool = False, timeout: float | None = None)[source]
Write actuator control values.
- Accepts three input shapes:
A flat sequence of floats: bulk write starting at index 0.
A dict[str, float]: write by actuator name.
A dict[int, float]: write by actuator index.
Actuators currently owned by an active RL agent are refused and returned in
SetControlResponse.rejected_actuators.
- list_all_joints(timeout: float | None = None) list[dict][source]
Return lightweight dicts for every joint in the loaded MuJoCo model.
- Convenience wrapper around
get_model_info(). Each entry: - {“index”: int, “name”: str, “type”: int, “qpos_adr”: int,
“qvel_adr”: int, “limited”: bool, “range”: (lo, hi)}
- Convenience wrapper around
- list_all_actuators(timeout: float | None = None) list[dict][source]
Return lightweight dicts for every actuator in the loaded MuJoCo model.
- get_agent_schema(agent_name: str = '', timeout: float | None = None)[source]
Get agent schema (observation/action sizes and names).
The schema is cached for subsequent step() calls to enable named access to observation values.
- Parameters:
agent_name – Agent name (empty = default agent).
timeout – RPC timeout.
- Returns:
GetAgentSchemaResponse with schema containing observation_names, action_names, observation_size, and action_size.
- reset_agent(agent_name: str = '', randomization_cfg: Any | None = None, timeout: float | None = None)[source]
Reset a specific agent.
- Parameters:
agent_name – Agent logical name. Empty string means default agent.
randomization_cfg – Optional simulation contract config for this reset.
timeout – Timeout in seconds (uses default if None).
- Returns:
ResetAgentResponse with success and message fields.
- step(actions: list[float] | None = None, agent_name: str = '', step_timeout_s: float = 0.0, timeout: float | None = None, action_groups: list[dict] | None = None) ObservationResponse[source]
Synchronous RL step: apply action, wait for physics, return observation.
- Parameters:
actions – Action vector to apply for this step (optional when using action_groups).
agent_name – Agent name (empty = default agent).
step_timeout_s – Server-side timeout for waiting for the physics step (seconds). 0 means use server default.
timeout – RPC timeout in seconds.
action_groups – Optional list of action group dicts, each with keys: group_name: str, actions: list[float], action_indices: list[int]. Groups are applied on top of actions (if provided) or default positions.
- Returns:
ObservationResponse with observation after physics step.
- report_progress(*, run_id: str = '', task_name: str = '', policy_name: str = '', phase: str = '', current_episode: int = 0, total_episodes: int = 0, current_step: int = 0, max_steps: int = 0, elapsed_s: float = 0.0, status_text: str = '', finished: bool = False) None[source]
Report evaluation/training progress to the engine for UI display.
Fire-and-forget: errors are logged but never raised.
- get_capability_manifest(robot_name: str = '', scene: str = '', timeout: float | None = None) dict[source]
Discover what MDP components the engine supports.
- Parameters:
robot_name – Filter by robot (empty = all).
scene – Filter by scene (empty = all).
timeout – RPC timeout in seconds.
- Returns:
Dict with observations, rewards, terminations, randomizations lists.
- validate_task_contract(contract: dict, timeout: float | None = None) dict[source]
Dry-run a task contract against the engine’s capability registry.
Validates without configuring anything — useful for CLI tooling and pre-flight checks. Errors include actionable suggestions (“did you mean track_angular_velocity?”).
- Parameters:
contract – Task contract dict (same shape as
negotiate_task).timeout – RPC timeout in seconds.
- Returns:
is_valid(bool),errors(list of dicts),warnings(list of dicts),resolved_optionals(list of term names that were resolved),unresolved_optionals.- Return type:
Dict with keys
- negotiate_task(contract: dict, timeout: float | None = None) dict[source]
Validate and configure engine for a task contract.
- Parameters:
contract – Task contract dict with observations, rewards, terminations, etc.
timeout – RPC timeout in seconds.
- Returns:
Dict with session_id, reward_terms, termination_terms on success.
- Raises:
RuntimeError – If contract validation fails.
- set_simulation_mode(mode: str = 'fast', timeout: float | None = None)[source]
Set simulation timing mode.
- Parameters:
mode – “realtime”, “deterministic”, or “fast” - realtime: Physics runs at 1x wall-clock speed - deterministic: Physics runs at fixed rate - fast: Physics runs as fast as possible (for RL training)
timeout – RPC timeout in seconds.
- Returns:
SetSimulationModeResponse with success and current mode.
- get_simulation_mode(timeout: float | None = None) str[source]
Query the engine’s current simulation timing mode.
- Returns:
One of
"realtime","deterministic","fast", or"unknown"if the engine returned an unrecognized enum value.
- enter_play_mode(timeout: float | None = None)[source]
Trigger the editor’s Edit -> Play transition over gRPC.
These RPCs are session boundaries, NOT pause/resume — entering Play recompiles MuJoCo and may take a moment to become ready. Returns immediately; poll
get_agent_schema()orget_model_info()to detect when the simulation is steppable. In standalone (dist) builds there is no Edit/Play distinction and this RPC is a no-op.Active recordings will be torn down when ExitPlayMode is later called (Play->Edit ends the recording session).
- exit_play_mode(timeout: float | None = None)[source]
Trigger the editor’s Play -> Edit transition over gRPC.
See
enter_play_mode()for the session-boundary semantics. Any in-flight recording is closed out as part of the transition.
- reset_scene(preserve_time: bool = False, timeout: float | None = None)[source]
Soft-reset the active MuJoCo scene back to its authored initial state.
Restores
qpostokeyframe[0](orqpos0if no keyframe is authored), zeroes velocities/forces/ctrl, and reseeds active PolicyRuntime PD targets so the policies don’t yank the robot back to a stale target on the next substep.Recording behaviour: recording continues across the reset by design. The first frame captured after the reset has the
post_resetbit (= 0x02) set in the newframe_flagscolumn so consumers can drop the qpos/ctrl discontinuity if needed.- Parameters:
preserve_time – Keep
mjData.timeintact across the reset. Default (False) zeroes time. Set True when in-flight RL training or data capture is tracking elapsed sim time.timeout – RPC timeout in seconds.
- get_scene_info(timeout: float | None = None) dict[source]
Return the active scene’s name, path, and entity count.
- list_entities(include_transforms: bool = False, include_components: bool = False, timeout: float | None = None) list[dict][source]
Enumerate entities in the active scene.
- Parameters:
include_transforms – Populate per-entity
transform.include_components – Populate per-entity
components(type names).timeout – RPC timeout in seconds.
- Returns:
List of dicts with keys
id,name, optionallytransform,components.
- get_entity(name: str | None = None, entity_id: int | None = None, timeout: float | None = None) dict | None[source]
Look up one entity by name or numeric id.
Returns the same dict shape as
list_entities()(always withtransformandcomponentspopulated), orNoneif not found.
- set_entity_transform(entity_id: int, position: tuple[float, float, float] | None = None, rotation: tuple[float, float, float, float] | None = None, scale: tuple[float, float, float] | None = None, timeout: float | None = None) bool[source]
Set an entity’s transform. Unspecified fields default to identity.
- Parameters:
entity_id – The entity’s numeric id (from
list_entities/get_entity).position –
(x, y, z)world-space position.rotation –
(x, y, z, w)quaternion.scale –
(x, y, z)scale.
- Returns:
Trueon success.
- get_telemetry_schema(timeout: float | None = None) dict[source]
Return the telemetry vector schema (observation names, action names, nq, nu).
Telemetry is the lightweight streaming surface — qpos + last-applied ctrl per frame. For full mjData (qpos/qvel/ctrl with filters), use
stream_full_state()on the MujocoScene wrapper instead.
- stream_telemetry(target_fps: int = 30)[source]
Iterate over server-streamed
TelemetryFrameprotos.Each frame carries
timestamp_ms,frame_number,observation_qpos(full mjData qpos), andaction_ctrl(last-applied ctrl). Cancellation-safe — break out of the loop to terminate the stream.
- get_viewport_info(timeout: float | None = None) dict[source]
List the viewports the engine exposes plus the current stream config.
On this engine branch the server reports a single
"Main"viewport.
- stream_viewport(viewport_name: str = 'Main', target_fps: int = 30, width: int = 0, height: int = 0, format: str = 'raw')[source]
Iterate over server-streamed
ImageFrameprotos for a viewport.- Parameters:
viewport_name – Viewport id (
"Main"is the only one on this engine branch).target_fps – Desired frame rate; server may clamp.
height (width /) – Desired resolution.
0= native.format –
"raw"(RGBA bytes) or"jpeg".
- stream_camera(name: str | None = None, entity_id: int | None = None, target_fps: int = 30, width: int = 0, height: int = 0, format: str = 'raw')[source]
Iterate over server-streamed
ImageFrameprotos for a camera.Identify by name (camera entity tag) or by numeric entity id. For synchronous in-step capture use
configure_cameras()plusstep()instead.
- stream_joint_state(robot_name: str | None = None)[source]
Iterate over server-streamed agent-scoped joint state.
Returns positions/velocities only for the joints declared by the registered
RobotAgent— not the full mjModel. For full-model streaming usestream_full_state()on the MujocoScene wrapper.
- benchmark(duration_seconds: float = 5.0, method: str = 'step', print_results: bool = False) BenchmarkResult[source]
Benchmark a client method by calling it in a tight loop.
- Parameters:
duration_seconds – How long to run the benchmark.
method – Method to benchmark. Currently supports “step”.
print_results – Print results to stdout.
- Returns:
BenchmarkResult with timing statistics.
- Raises:
ValueError – If method is not recognized.
GrpcConnectionError
Models
Engine Management
Engine Lifecycle
Engine lifecycle management for LuckyEngine.