Skip to main content

A robotics experimentation framework that transforms PyBullet robots into intuitive Python objects, with modern ImGui-based controls, telemetry, visualization, and reinforcement learning workflows.

Project description

BulletLab

Developed by Ranasurya Ghosh

A fast, extensible robotics experimentation framework built on PyBullet, designed for rapid prototyping, testing, simulation and learning.

Python 3.10 License: MIT

Install BulletLab library: pip install bulletlab
Read Documentation

BulletLab example UI


What is BulletLab?

BulletLab provides a high-level object-oriented interface to PyBullet that simplifies robotics experimentation by exposing joints, links, sensors, and environments as intuitive Python objects instead of raw physics engine IDs. It combines real-time simulation with a ImGui-powered modern interface for interactive control, parameter tuning, telemetry visualization, and experiment management, while also offering reinforcement learning integration for training and evaluating autonomous robotic systems within a unified workflow.

Instead of this:

p.setJointMotorControl2(
    robot_id, joint_index,
    controlMode=p.VELOCITY_CONTROL,
    targetVelocity=15,
    force=100
)

You write this:

robot.joints["motor"].velocity = 15

Architecture

BulletLab uses a two-window architecture:

Window Purpose
PyBullet Native Window Physics simulation, 3D rendering, camera
BulletLab ImGui Window Control panels, telemetry, live plots, console

These windows communicate through Python objects. BulletLab does not attempt to replace PyBullet's renderer or embed ImGui inside the simulation viewport.


Quick Start

Installation

pip install bulletlab
# or from source:
pip install -e .

Basic Example

from bulletlab import Simulation, Robot
from bulletlab.ui import BulletLabUI

# Create simulation
sim = Simulation()
sim.start()

# Load robot
robot = Robot.load("path/to/robot.urdf", sim=sim)

# Control joints by name
robot.joints["wheel_left"].velocity = 10
robot.joints["wheel_right"].velocity = 10

# Modify physics parameters
robot.links["chassis"].mass = 5.0
robot.links["wheel_fl"].friction = 1.2

# Get robot state
state = robot.get_state()
print(f"Position: {robot.base_position}")
print(f"Roll: {robot.roll:.2f}°")

# Build UI
ui = BulletLabUI(sim=sim)
ui.register_panel(...)
ui.run()

Telemetry & Logging

from bulletlab.telemetry import TelemetryManager
from bulletlab.logging import DataLogger

telemetry = TelemetryManager()
telemetry.watch("Speed", lambda: robot.base_velocity[0])
telemetry.watch("Roll",  lambda: robot.roll)

logger = DataLogger()
logger.watch("speed", lambda: robot.base_velocity[0])
logger.start("run1.csv")

for _ in range(1000):
    sim.step()
    telemetry.update()
    logger.step()

logger.stop()

Live Plotting

from bulletlab.plotting import LivePlot

plot = LivePlot(title="Robot Speed")
plot.watch("Speed", lambda: robot.base_velocity[0], color="#00ff88")
plot.start()

for _ in range(1000):
    sim.step()
    plot.update()

ImGui Control Panel

from bulletlab.ui import BulletLabUI
from bulletlab.ui import widgets as ui

app = BulletLabUI(sim=sim, robots=[robot])

@app.custom_panel("My Controls")
def my_panel():
    ui.button("Reset", robot.reset)
    ui.slider("Wheel Mass", robot.links["wheel"].mass, 0.1, 20,
              setter=lambda v: setattr(robot.links["wheel"], "mass", v))
    ui.checkbox("Motors Enabled", lambda: motors_on,
                setter=lambda v: toggle_motors(v))

app.run()

Supported Robot Types

BulletLab is completely generic — no code assumes a specific robot type:

  • Cars & rovers
  • Drones & quadrotors
  • Robotic arms
  • Self-balancing robots
  • Quadrupeds
  • Humanoids
  • Custom mechanisms

Reinforcement Learning

BulletLab exposes clean state/action interfaces without depending on any ML framework:

# Compatible with any RL approach
state = robot.get_state()      # → numpy array
action = my_policy(state)      # → numpy array
robot.apply_action(action)     # → updates joints

# Manual Q-learning, SARSA, evolutionary algorithms — all supported

Examples

Example Description
examples/01_differential_drive_rover.py Rover with wheel velocity control
examples/02_robotic_arm.py Joint position control with ImGui sliders
examples/03_self_balancing_robot.py PD controller for balance
examples/04_drone_parameter_tuning.py Thrust/mass parameter exploration
examples/05_generic_robot_inspector.py Load any URDF and inspect it

Run any example:

python examples/01_differential_drive_rover.py

Documentation

pip install -e ".[dev]"
mkdocs serve

Then visit http://localhost:8000


Testing

pip install -e ".[dev]"
pytest tests/ -v --cov=bulletlab --cov-report=term-missing

Technology Stack

Component Library
Physics PyBullet
UI Dear ImGui (pyimgui)
Data NumPy, Pandas
Config PyYAML
Plotting PyQtGraph
Testing PyTest
Docs MkDocs + mkdocstrings

License

MIT License — see LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bulletlab-0.1.1.tar.gz (75.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bulletlab-0.1.1-py3-none-any.whl (54.2 kB view details)

Uploaded Python 3

File details

Details for the file bulletlab-0.1.1.tar.gz.

File metadata

  • Download URL: bulletlab-0.1.1.tar.gz
  • Upload date:
  • Size: 75.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.0

File hashes

Hashes for bulletlab-0.1.1.tar.gz
Algorithm Hash digest
SHA256 057e3654616de5e9d454cef2c4c9e9dcdd849e7e5f1f9c89647555f6e61ba068
MD5 7918f51bcb330a03cd0bc35e73d885c1
BLAKE2b-256 0e7db66a93e0da84a8e3236cdea9f622b9ecf0945c84abfcce9195cdb19eb468

See more details on using hashes here.

File details

Details for the file bulletlab-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: bulletlab-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 54.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.0

File hashes

Hashes for bulletlab-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 5c6567fdc86f1cb482cf21e139c0c44f3adf336a8af168630677b182224d8a28
MD5 89d3594407e0028406591a2367967d30
BLAKE2b-256 61bbb4c305b8cb95ecda022fe0763a0f67587028e08547f11f34ba416e79734f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page