Skip to content

simulo.Robot

The robot authoring contract — a multi-joint articulated system.

This is the surface authoring code may rely on when it creates a robot, adds it to a scene, and controls it: construction-time configuration, joint/body name queries, command targets (position, velocity, effort), state reads, and reset. Values that carry per-environment batches are typed TensorLike — the contract does not bind to a tensor library.

Real usage, from the shipped cartpole training app: construct with an Asset and a Pose, add it to the scene, then look up joint indices once and drive them every step:

self.robot = simulo.Robot(asset=cartpole, initial_pose=simulo.Pose.identity())
scene.add(self.robot, at="/World/Robot")
# later, once — resolve joint indices by name:
self._cart_dof_idx = self.robot.find_joints("slider_to_cart")
# every step — drive the resolved joints:
self.robot.set_joint_effort_target(
self.action_scale * actions, joint_ids=self._cart_dof_idx
)

robot.state (e.g. robot.state.joint_positions) is the supported, typed way to read state back. Six members are live views; the two base-frame velocity members are computed on every read. robot.state.linear_velocity_in_base_frame and robot.state.angular_velocity_in_base_frame express base velocity in robot coordinates. robot.default_joint_positions, robot.default_joint_velocities, and robot.default_pose expose safe copies of the values robot.reset(env_ids) writes.

Robot.asset: AssetSource

Model source (USD or URDF) defining the robot.

Robot.initial_pose: Pose

Pose the robot spawns at (identity when not given). For a robot copied into each environment, the position is measured from that environment’s origin, and default_pose reports it with the origin added. For some catalog robots, such as the cartpole, the identity pose keeps the catalog model’s own spawn height; any other pose replaces it. A robot added under a Transform spawns at the Transform’s position.

Robot.collision_enabled: bool

Whether collision detection is enabled.

Robot.visual_only: bool

If True, the robot is spawned visual-only, with no physics.

Robot.mass_scale: float

Scale factor applied to all link masses.

Robot.scale: Tuple[float, float, float]

Per-axis spawn scale factor.

Robot.articulation: Any

Articulation physics and control configuration.

Robot.joint_config: Optional[List[Any]]

Optional per-joint configurations.

Robot.disable_gravity: bool

If True, gravity is disabled for this robot.

Robot.actuator_gains: Optional[Dict[str, Any]]

Optional mapping of actuator-group names to gain configurations.

Robot.name: Optional[str]

property

Robot name — set by the scene when the robot is added.

Robot.path: Optional[str]

property

Scene path — set by the scene when the robot is added.

Robot.internals: Any

property

The engine’s internal data object, for direct tensor access.

An explicitly engine-specific, unstable escape hatch: which attributes the returned object exposes depends on the simulation engine, is not part of this contract, and carries no compatibility promise — reaching into it is at your own risk. The supported, typed way to read live robot state is state. Raises RuntimeError until the simulation runtime has attached the robot — read it from on_start onward.

Robot.state: RobotStateProtocol

property

The grouped live robot state — the supported, typed state surface.

Always available (the accessor is the same object on every access); six members read straight through to the simulation’s state buffers, while the two base-frame velocity members are computed into new tensors on every read. Members raise RuntimeError until the simulation runtime has attached the robot — read them from on_start onward.

Robot.default_joint_positions: TensorLike

property

Joint positions that reset() writes, shape (num_envs, num_joints) in rad for hinge joints and m for slider joints. Columns use the same order as state.joint_positions and the indices returned by find_joints(). Available from on_start onward. Each read returns a new tensor, so writing into it cannot change a later reset.

Robot.default_joint_velocities: TensorLike

property

Joint velocities that reset() writes, shape (num_envs, num_joints) in rad/s for hinge joints and m/s for slider joints. Columns use the same order as state.joint_positions and the indices returned by find_joints(). Available from on_start onward. Each read returns a new tensor, so writing into it cannot change a later reset.

Robot.default_pose: TensorLike

property

Base pose that reset() writes in the world frame.

Columns are [x, y, z, qw, qx, qy, qz]: position in m followed by a w-first unit quaternion. For a robot added with per_environment=True (the default), the shape is (num_envs, 7) and each environment’s origin is included. For a robot added with per_environment=False, this is one row containing its authored world pose with no environment origin. A shared robot is supported only when the scene has one environment; scene building refuses per_environment=False for a robot when num_envs > 1. Available from on_start onward. Each read returns a new tensor, so writing into it cannot change a later reset.

Robot.sensors: List[Any]

property

Sensors attached to this robot via add_sensor().

Robot.actuators: List[Any]

property

Actuators attached to this robot via add_actuator().

Robot.num_joints: int

property

Number of joints in the robot.

Robot.is_fixed_base: bool

property

Whether the robot’s base is fixed (not floating).

Robot.add_sensor(sensor: Any, attach_to: str) -> RobotProtocol

Attach a sensor at a point relative to the robot root; returns the robot for chaining. The sensor is registered with the scene automatically when the robot is added.

Robot.add_actuator(actuator: Any, attach_to: str) -> RobotProtocol

Attach an actuator at a point relative to the robot root; returns the robot for chaining. The actuator is registered with the scene automatically when the robot is added.

Robot.get_joint_names() -> List[str]

Ordered list of joint names.

Robot.find_joints(name_pattern: str) -> List[int]

Joint indices whose names match name_pattern (exact or regex).

Robot.find_bodies(name_pattern: str) -> List[int]

Body/link indices whose names match name_pattern (exact or regex).

Robot.get_jacobians(body_indices: Optional[List[int]] = ...) -> Optional[TensorLike]

Jacobian matrices for the given bodies, shape (num_envs, num_bodies, 6, num_joints); None when unavailable.

Robot.get_mass_matrix(joint_ids: Optional[List[int]] = ...) -> Optional[TensorLike]

Generalized mass matrix, shape (num_envs, num_joints, num_joints); None when unavailable.

Robot.get_gravity_compensation(joint_ids: Optional[List[int]] = ...) -> Optional[TensorLike]

Joint torques that counteract gravity, shape (num_envs, num_joints); None when unavailable.

Robot.get_body_velocity_in_base_frame(body_name: str) -> Optional[Tuple[TensorLike, TensorLike]]

(linear_velocity, angular_velocity) of a body relative to the robot’s base frame, each (num_envs, 3); (None, None) when unavailable.

Robot.get_body_pose_in_base_frame(body_name: str) -> Optional[Any]

(position, quaternion) of a body relative to the robot’s base frame; (None, None) when unavailable.

Robot.set_joint_state(
positions: TensorLike,
velocities: Optional[TensorLike] = ...,
env_ids: Optional[TensorLike] = ...,
) -> None

Write joint positions/velocities directly (teleport or reset, not control).

Robot.set_joint_position_target(
positions: TensorLike,
joint_ids: Optional[TensorLike] = ...,
env_ids: Optional[TensorLike] = ...,
) -> None

Set target joint positions for position control.

Robot.set_joint_velocity_target(
velocities: TensorLike,
joint_ids: Optional[TensorLike] = ...,
env_ids: Optional[TensorLike] = ...,
) -> None

Set target joint velocities for velocity control.

Robot.set_joint_effort_target(
efforts: TensorLike,
joint_ids: Optional[TensorLike] = ...,
) -> None

Set target joint efforts (torques/forces). Commands are buffered and flushed automatically before the next physics step.

Robot.set_root_pose(pose: TensorLike, env_ids: Optional[TensorLike] = ...) -> None

Set the base pose directly (teleport, not control), world frame, shape (num_envs, 7).

Robot.set_root_velocity(velocity: TensorLike, env_ids: Optional[TensorLike] = ...) -> None

Set the base velocity directly (teleport, not control), world frame, shape (num_envs, 6).

Robot.get_body_pose(body_name: str) -> Optional[TensorLike]

Pose of a body in the world frame, shape (num_envs, 7); None when unavailable.

Robot.get_body_velocity(body_name: str) -> Optional[TensorLike]

Velocity of a body in the world frame, shape (num_envs, 6); None when unavailable.

Robot.get_joint_state() -> Tuple[Optional[TensorLike], Optional[TensorLike]]

(joint_positions, joint_velocities), each (num_envs, num_joints); (None, None) when unavailable.

Robot.get_root_pose() -> Optional[TensorLike]

Base pose in the world frame, shape (num_envs, 7); None when unavailable.

Robot.get_root_velocity() -> Optional[TensorLike]

Base velocity in the world frame, shape (num_envs, 6); None when unavailable.

Robot.reset(env_ids: Optional[TensorLike] = ...) -> None

Reset the robot to its default state for the given environments (all environments when not given).

Robot.reset_to_default() -> None

Reset all environments to the default joint state.

Robot.update(dt: float) -> None

Refresh the robot’s state from the simulation. Called automatically each step by the runtime.


Declared as:

@runtime_checkable
class RobotProtocol(Protocol)

The live robot-state contract — batched and read-only.

Obtained from a robot as robot.state; never constructed directly. Six members (pose, the two world-frame velocities, and the three joint_* members) are zero-copy live views of the simulation’s own buffers. linear_velocity_in_base_frame and angular_velocity_in_base_frame are computed from the current base orientation on every read. Each of those reads returns a new tensor, costs a small computation, and cannot modify the simulation when written into. All members carry the environment batch as their leading dimension (the scene’s num_envs).

Read a member each time you need it — do not hold the returned tensor across steps, and do not write into it. The six live-view tensors share simulation memory, and writing into one writes into the simulation. The engine can also rebind those buffers, while the base-frame members are recomputed, so a tensor held across a step can silently serve stale values. The accessor (robot.state itself) may be held freely; the tensors its members return should be re-read at each use.

Members raise RuntimeError until the simulation runtime has attached the robot — read them from on_start onward. The state accessor itself is always available and is the same object on every access.

These eight names are a compatibility promise: they keep working across engine upgrades. For anything not named here, the internals escape hatch remains available — explicitly unstable, at your own risk.

state.pose: TensorLike

property

Base pose in the world frame, shape (num_envs, 7): [x, y, z, qw, qx, qy, qz] (position + w-first quaternion).

state.linear_velocity: TensorLike

property

Base linear velocity in the world frame, shape (num_envs, 3): [vx, vy, vz].

state.angular_velocity: TensorLike

property

Base angular velocity in the world frame, shape (num_envs, 3): [wx, wy, wz].

state.linear_velocity_in_base_frame: TensorLike

property

Base linear velocity expressed in the base frame, shape (num_envs, 3) in m/s with columns [vx, vy, vz]. Available from on_start onward. Computed from the current base orientation on every read; each read returns a new tensor, costs a small computation, and writing into it does not reach the simulation.

state.angular_velocity_in_base_frame: TensorLike

property

Base angular velocity expressed in the base frame, shape (num_envs, 3) in rad/s with columns [wx, wy, wz]. Available from on_start onward. Computed from the current base orientation on every read; each read returns a new tensor, costs a small computation, and writing into it does not reach the simulation.

state.joint_positions: TensorLike

property

Joint positions (rad or m), shape (num_envs, num_joints).

state.joint_velocities: TensorLike

property

Joint velocities (rad/s or m/s), shape (num_envs, num_joints).

state.joint_efforts: TensorLike

property

Joint efforts actually applied by the actuators (N·m or N), shape (num_envs, num_joints).


Declared as:

@runtime_checkable
class RobotStateProtocol(Protocol)