Robot Guide
This guide covers everything about loading and controlling robots in BulletLab.
Loading Robots
BulletLab supports URDF and MJCF formats. Use Robot.load():
from bulletlab import Simulation, Robot
sim = Simulation().start()
# Load from pybullet_data (by relative path)
robot = Robot.load("kuka_iiwa/model.urdf", sim=sim)
# Load with custom position and orientation
robot = Robot.load(
"my_robot.urdf",
sim=sim,
position=(0, 0, 0.5),
orientation=(0, 0, 0, 1), # quaternion (x, y, z, w)
fixed_base=False,
scale=1.0,
name="MyRobot",
)
Accessing Joints
Joints are accessible by name via robot.joints:
# List all joints
print(list(robot.joints.keys()))
# Access a specific joint
joint = robot.joints["iiwa_joint_1"]
print(joint.position) # current angle (rad)
print(joint.velocity) # current velocity (rad/s)
print(joint.torque) # applied torque (N·m)
print(joint.limits) # (lower, upper) in rad
print(joint.is_fixed) # True for fixed joints
Controlling Joints
Velocity Control
Position Control
Torque Control
Resetting
Accessing Links
Links are accessible by name via robot.links:
# List all links
print(list(robot.links.keys()))
# Access the base link
base = robot.links["base"]
print(base.mass) # mass in kg
print(base.position) # world position (x, y, z)
print(base.velocity) # linear velocity (vx, vy, vz)
Modifying Link Properties
All property setters call pybullet.changeDynamics immediately:
robot.links["chassis"].mass = 5.0
robot.links["wheel_fl"].friction = 1.2
robot.links["bumper"].restitution = 0.5
robot.links["chassis"].linear_damping = 0.1
robot.links["chassis"].angular_damping = 0.05
Base State
robot.base_position # (x, y, z) in meters
robot.base_orientation # (x, y, z, w) quaternion
robot.base_velocity # (vx, vy, vz) m/s
robot.base_angular_velocity # (wx, wy, wz) rad/s
robot.roll # roll angle in rad
robot.pitch # pitch angle in rad
robot.yaw # yaw angle in rad
robot.speed # scalar speed in m/s
Resetting the Robot
# Reset to original load position
robot.reset()
# Reset to a specific pose
robot.reset(position=(0, 0, 1), orientation=(0, 0, 0, 1))
RL-Compatible Interface
# Get flat state vector (numpy array)
state = robot.get_state()
# [x, y, z, qx, qy, qz, qw, vx, vy, vz, wx, wy, wz, j0_pos, j1_pos, ..., j0_vel, j1_vel, ...]
# Apply velocity actions
action = my_policy(state) # → numpy array of velocities
robot.apply_action(action) # applies to all controllable joints
# Apply torque actions
robot.apply_torques(torques)