Skip to content

PyBullet tutorials and learning

Simulation / PyBullet

  • URDF
  • Types of joints
  • Robot Coordination
  • Task Space
  • Joint/Configuration space
  • Base position, orientation

urdf

online play

Types of joints

  • Fixed: rigid connection, no motion
  • Revolute: support rotation in 1 dimension (along a single axis)
  • Continuous: unlimited variant of revolute joints
  • Prismatic: support translation in 1 dimension (along a single axis)
  • Planar: translation in two dimensions
  • Floating: unlimited motion (translation and rotation) in all 6 dimentions

alt text

PyBullet Constant Integer Meaning
p.JOINT_REVOLUTE 0 Standard hinge joint
p.JOINT_PRISMATIC 1 Linear slider
p.JOINT_SPHERICAL 2 3-DOF ball joint
p.JOINT_PLANAR 3 Planar joint
p.JOINT_FIXED 4 Fixed (no movement)
p.JOINT_POINT2POINT 5 P2P constraint
p.JOINT_GEAR 6 Gear ratio constraint

Demo: RRBot

urdf
<?xml version="1.0"?>
<robot name="rrbot">

  <!-- ====================== -->
  <!--        LINKS           -->
  <!-- ====================== -->

  <!-- Base link -->
  <link name="base_link">
    <inertial>
      <origin xyz="0 0 0" rpy="0 0 0" />
      <mass value="1.0"/>
      <inertia
        ixx="0.1" ixy="0.0" ixz="0.0"
        iyy="0.1" iyz="0.0"
        izz="0.1"/>
    </inertial>
    <visual>
      <origin xyz="0 0 0" rpy="0 0 0" />
      <geometry>
        <box size="0.4 0.4 0.2"/>
      </geometry>
      <material name="blue">
        <color rgba="0 0 1 1"/>
      </material>
    </visual>
    <collision>
      <origin xyz="0 0 0" rpy="0 0 0" />
      <geometry>
        <box size="0.4 0.4 0.2"/>
      </geometry>
    </collision>
  </link>

  <!-- Link1 -->
  <link name="link1">
    <inertial>
      <origin xyz="0 0 0.5" rpy="0 0 0"/>
      <mass value="1.0"/>
      <inertia
        ixx="0.1" ixy="0.0" ixz="0.0"
        iyy="0.1" iyz="0.0"
        izz="0.1"/>
    </inertial>
    <visual>
      <origin xyz="0 0 0.5" rpy="0 0 0"/>
      <geometry>
        <cylinder radius="0.05" length="1.0"/>
      </geometry>
      <material name="yellow">
        <color rgba="1 1 0 1"/>
      </material>
    </visual>
    <collision>
      <origin xyz="0 0 0.5" rpy="0 0 0"/>
      <geometry>
        <cylinder radius="0.05" length="1.0"/>
      </geometry>
    </collision>
  </link>

  <!-- Link2 -->
  <link name="link2">
    <inertial>
      <origin xyz="0 0 0.5" rpy="0 0 0"/>
      <mass value="1.0"/>
      <inertia
        ixx="0.1" ixy="0.0" ixz="0.0"
        iyy="0.1" iyz="0.0"
        izz="0.1"/>
    </inertial>
    <visual>
      <origin xyz="0 0 0.5" rpy="0 0 0"/>
      <geometry>
        <cylinder radius="0.05" length="1.0"/>
      </geometry>
      <material name="red">
        <color rgba="1 0 0 1"/>
      </material>
    </visual>
    <collision>
      <origin xyz="0 0 0.5" rpy="0 0 0"/>
      <geometry>
        <cylinder radius="0.05" length="1.0"/>
      </geometry>
    </collision>
  </link>


  <!-- ====================== -->
  <!--        JOINTS          -->
  <!-- ====================== -->

  <!-- Joint1: base_link → link1 -->
  <joint name="joint_1" type="revolute">
    <origin xyz="0 0 0.1" rpy="0 0 0"/>
    <parent link="base_link"/>
    <child link="link1"/>
    <axis xyz="0 0 1"/> <!-- rotates around Z -->
    <limit lower="-3.14" upper="3.14" effort="10" velocity="1.0"/>
  </joint>

  <!-- Joint2: link1 → link2 -->
  <joint name="joint_2" type="revolute">
    <origin xyz="0 0 1.0" rpy="0 0 0"/>
    <parent link="link1"/>
    <child link="link2"/>
    <axis xyz="0 1 0"/> <!-- rotates around Y -->
    <limit lower="-3.14" upper="3.14" effort="10" velocity="1.0"/>
  </joint>



</robot>

Joint name and types

import pybullet as p
import time
import pybullet_data


p.connect(p.GUI)
p.setGravity(0, 0, -9.8)

# Default PyBullet assets
p.setAdditionalSearchPath(pybullet_data.getDataPath())
plane_id = p.loadURDF("plane.urdf")

p.setAdditionalSearchPath("/workspace/demos/urdf")
robot_id = p.loadURDF("rrbot.urdf", useFixedBase=True)
# Print joint information
num_joints = p.getNumJoints(robot_id)
print("Total joints:", num_joints)
for i in range(num_joints):
    info = p.getJointInfo(robot_id, i)
    print(i, info[1].decode("utf-8"), "| type =", info[2])

while p.isConnected():
    p.stepSimulation()
    time.sleep(1./240.)
output
1
2
3
4
5
---
Total joints: 2
0 joint_1 | type = 0
1 joint_2 | type = 0
---

Joint command


Reference