CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pybullet

Official Python Interface for the Bullet Physics SDK specialized for Robotics Simulation and Reinforcement Learning

Pending
Overview
Eval results
Files

physics-configuration.mddocs/

Physics Configuration

Configure simulation parameters, gravity, time stepping, and advanced physics engine settings for optimal performance and realistic behavior. Essential for tuning simulations for specific applications and achieving desired accuracy-performance trade-offs.

Capabilities

Gravity and Global Forces

Set global forces that affect all objects in the simulation.

def setGravity(gravX, gravY, gravZ, physicsClientId=0):
    """
    Set gravity acceleration vector for the simulation.
    
    Args:
        gravX (float): Gravity acceleration in X direction (m/s²)
        gravY (float): Gravity acceleration in Y direction (m/s²)
        gravZ (float): Gravity acceleration in Z direction (m/s²)
        physicsClientId (int, optional): Physics client ID. Defaults to 0.
    
    Note:
        Earth gravity: [0, 0, -9.81]
        Moon gravity: [0, 0, -1.62]
        Zero gravity: [0, 0, 0]
        Custom directions: e.g., [0, -9.81, 0] for Y-up coordinate system
    """

Time Stepping

Control simulation timing and temporal resolution.

def setTimeStep(timeStep, physicsClientId=0):
    """
    Set simulation time step size.
    
    Args:
        timeStep (float): Time step in seconds (typically 1/240 to 1/60)
        physicsClientId (int, optional): Physics client ID. Defaults to 0.
    
    Note:
        Smaller time steps provide higher accuracy but slower simulation.
        Common values:
        - 1/240 (0.00416s): High precision, good for complex simulations
        - 1/120 (0.00833s): Good balance of speed and accuracy
        - 1/60 (0.01667s): Fast simulation, lower accuracy
    """

Contact Parameters

Configure contact behavior and error correction.

def setDefaultContactERP(defaultContactERP, physicsClientId=0):
    """
    Set default Error Recovery Parameter for contact constraints.
    
    Args:
        defaultContactERP (float): ERP value (0.0 to 1.0)
        physicsClientId (int, optional): Physics client ID. Defaults to 0.
    
    Note:
        ERP controls how quickly interpenetration is resolved.
        Higher values = faster resolution but less stability.
        Typical range: 0.1 to 0.8
    """

Advanced Physics Engine Parameters

Fine-tune internal physics engine behavior for performance and accuracy.

def setPhysicsEngineParameter(fixedTimeStep=None, numSolverIterations=None, useSplitImpulse=None, splitImpulsePenetrationThreshold=None, numSubSteps=None, collisionFilterMode=None, contactBreakingThreshold=None, maxNumCmdPer1ms=None, enableFileCaching=None, restitutionVelocityThreshold=None, erp=None, contactERP=None, frictionERP=None, enableConeFriction=None, deterministicOverlappingPairs=None, allowedCcdPenetration=None, jointFeedbackMode=None, solverResidualThreshold=None, contactSlop=None, enableSAT=None, constraintSolverType=None, minimumSolverIslandSize=None, reportSolverAnalytics=None, warmStartingFactor=None, articulatedWarmStartingFactor=None, physicsClientId=0):
    """
    Set advanced physics engine parameters for fine-tuning performance and behavior.
    
    Args:
        fixedTimeStep (float, optional): Fixed time step size override
        numSolverIterations (int, optional): Number of constraint solver iterations (default: 50)
        useSplitImpulse (int, optional): Use split impulse for penetration recovery (0/1)
        splitImpulsePenetrationThreshold (float, optional): Threshold for split impulse activation
        numSubSteps (int, optional): Number of sub-steps per simulation step (default: 1)
        collisionFilterMode (int, optional): Collision filtering mode
        contactBreakingThreshold (float, optional): Distance threshold for contact breaking
        maxNumCmdPer1ms (int, optional): Maximum commands processed per millisecond
        enableFileCaching (int, optional): Enable file caching for faster loading (0/1)
        restitutionVelocityThreshold (float, optional): Velocity threshold for restitution
        erp (float, optional): Global error recovery parameter
        contactERP (float, optional): Contact-specific ERP
        frictionERP (float, optional): Friction-specific ERP
        enableConeFriction (int, optional): Enable cone friction model (0/1)
        deterministicOverlappingPairs (int, optional): Deterministic overlapping pair handling (0/1)
        allowedCcdPenetration (float, optional): Allowed penetration for CCD
        jointFeedbackMode (int, optional): Joint feedback computation mode
        solverResidualThreshold (float, optional): Solver convergence threshold
        contactSlop (float, optional): Contact slop parameter for stability
        enableSAT (int, optional): Enable Separating Axis Theorem (0/1)
        constraintSolverType (int, optional): Constraint solver algorithm type
        minimumSolverIslandSize (int, optional): Minimum size for solver islands
        reportSolverAnalytics (int, optional): Enable solver analytics reporting (0/1)
        warmStartingFactor (float, optional): Warm starting factor for solver
        articulatedWarmStartingFactor (float, optional): Warm starting for articulated bodies
        physicsClientId (int, optional): Physics client ID. Defaults to 0.
    
    Note:
        These parameters significantly affect simulation behavior and performance.
        Modify carefully and test thoroughly. Default values work well for most applications.
    """

def getPhysicsEngineParameters(physicsClientId=0):
    """
    Get current physics engine parameters.
    
    Args:
        physicsClientId (int, optional): Physics client ID. Defaults to 0.
    
    Returns:
        dict: Dictionary containing all current physics engine parameters
    """

Internal Simulation Flags

Control experimental and advanced simulation features.

def setInternalSimFlags(flags, physicsClientId=0):
    """
    Set internal simulation flags (experimental features).
    
    Args:
        flags (int): Bitwise combination of internal simulation flags
        physicsClientId (int, optional): Physics client ID. Defaults to 0.
    
    Warning:
        These are experimental features that may change or be removed.
        Use with caution in production code.
    """

Configuration Presets

High Precision Configuration

import pybullet as p

def setupHighPrecisionPhysics():
    """Configure physics for maximum accuracy."""
    p.setTimeStep(1./240.)  # Small time step
    p.setGravity(0, 0, -9.81)
    
    p.setPhysicsEngineParameter(
        numSolverIterations=100,  # More solver iterations
        useSplitImpulse=1,
        splitImpulsePenetrationThreshold=-0.001,
        contactBreakingThreshold=0.001,
        solverResidualThreshold=1e-7,
        numSubSteps=1
    )

High Performance Configuration

import pybullet as p

def setupHighPerformancePhysics():
    """Configure physics for maximum speed."""
    p.setTimeStep(1./60.)  # Larger time step
    p.setGravity(0, 0, -9.81)
    
    p.setPhysicsEngineParameter(
        numSolverIterations=20,  # Fewer iterations
        useSplitImpulse=0,
        enableFileCaching=1,
        numSubSteps=1,
        deterministicOverlappingPairs=0
    )

Robotics Configuration

import pybullet as p

def setupRoboticsPhysics():
    """Configure physics optimized for robotics applications."""
    p.setTimeStep(1./240.)
    p.setGravity(0, 0, -9.81)
    
    p.setPhysicsEngineParameter(
        numSolverIterations=50,
        useSplitImpulse=1,
        splitImpulsePenetrationThreshold=-0.004,
        contactBreakingThreshold=0.001,
        restitutionVelocityThreshold=0.2,
        enableConeFriction=1,
        warmStartingFactor=0.85
    )

Soft Body Configuration

import pybullet as p

def setupSoftBodyPhysics():
    """Configure physics for soft body simulation."""
    p.setTimeStep(1./240.)
    p.setGravity(0, 0, -9.81)
    
    p.setPhysicsEngineParameter(
        numSolverIterations=150,  # More iterations for soft bodies
        useSplitImpulse=1,
        numSubSteps=4,  # More sub-steps for stability
        contactBreakingThreshold=0.0001,
        solverResidualThreshold=1e-6
    )

Usage Examples

Basic Physics Setup

import pybullet as p

p.connect(p.GUI)

# Standard Earth-like physics
p.setGravity(0, 0, -9.81)
p.setTimeStep(1./240.)

# Load objects and run simulation
robotId = p.loadURDF("pr2_gripper.urdf")

for step in range(1000):
    p.stepSimulation()

Custom Gravity Environment

import pybullet as p

p.connect(p.GUI)

# Simulate low gravity environment (Moon-like)
p.setGravity(0, 0, -1.62)  # Moon gravity
p.setTimeStep(1./240.)

# Or simulate microgravity
# p.setGravity(0, 0, -0.01)

# Load objects - they will fall slowly
cubeId = p.loadURDF("cube.urdf", [0, 0, 2])

for step in range(2000):  # Longer simulation to see slow motion
    p.stepSimulation()

Performance Optimization Example

import pybullet as p
import time

p.connect(p.DIRECT)  # No GUI for maximum performance

# Performance-optimized settings
p.setTimeStep(1./60.)  # Larger time step
p.setGravity(0, 0, -9.81)

# Optimize physics engine
p.setPhysicsEngineParameter(
    numSolverIterations=20,     # Reduce solver iterations
    enableFileCaching=1,        # Enable caching
    deterministicOverlappingPairs=0,  # Faster collision detection
    useSplitImpulse=0          # Disable for speed
)

# Load many objects for stress test
objects = []
for i in range(100):
    x = (i % 10) * 0.5
    y = (i // 10) * 0.5
    objId = p.loadURDF("cube.urdf", [x, y, 1])
    objects.append(objId)

# Measure performance
start_time = time.time()
num_steps = 1000

for step in range(num_steps):
    p.stepSimulation()

end_time = time.time()
elapsed = end_time - start_time
fps = num_steps / elapsed

print(f"Simulation FPS: {fps:.1f}")
print(f"Simulated time: {num_steps * (1./60.):.2f} seconds")
print(f"Real time: {elapsed:.2f} seconds")
print(f"Speed ratio: {(num_steps * (1./60.)) / elapsed:.1f}x real-time")

Precision Testing and Tuning

import pybullet as p
import numpy as np

def testPhysicsAccuracy(timeStep, solverIterations):
    """Test physics accuracy with different parameters."""
    p.resetSimulation()
    p.setTimeStep(timeStep)
    p.setGravity(0, 0, -9.81)
    
    p.setPhysicsEngineParameter(numSolverIterations=solverIterations)
    
    # Drop object from known height
    cubeId = p.loadURDF("cube.urdf", [0, 0, 5])
    
    # Theoretical time to fall: t = sqrt(2h/g) = sqrt(10/9.81) ≈ 1.01s
    theoretical_time = np.sqrt(10 / 9.81)
    
    positions = []
    times = []
    
    for step in range(int(theoretical_time * 1.5 / timeStep)):
        p.stepSimulation()
        pos, _ = p.getBasePositionAndOrientation(cubeId)
        positions.append(pos[2])
        times.append(step * timeStep)
        
        # Stop when object hits ground
        if pos[2] < 0.05:
            actual_time = step * timeStep
            break
    
    error = abs(actual_time - theoretical_time)
    return actual_time, theoretical_time, error

# Test different configurations
configs = [
    (1./240., 50),   # Standard
    (1./120., 50),   # Faster time step
    (1./240., 20),   # Fewer iterations
    (1./240., 100),  # More iterations
]

print("TimeStep | Iterations | Actual | Theoretical | Error")
print("-" * 50)

for timeStep, iterations in configs:
    p.connect(p.DIRECT)
    actual, theoretical, error = testPhysicsAccuracy(timeStep, iterations)
    print(f"{timeStep:8.5f} | {iterations:10d} | {actual:6.3f} | {theoretical:11.3f} | {error:5.3f}")
    p.disconnect()

Dynamic Parameter Adjustment

import pybullet as p

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

# Start with standard settings
p.setTimeStep(1./240.)
p.setPhysicsEngineParameter(numSolverIterations=50)

robotId = p.loadURDF("kuka_iiwa/model.urdf")

simulation_phase = 0
step_count = 0

for total_step in range(3000):
    # Change physics parameters during simulation
    if total_step == 1000:
        print("Switching to high precision mode...")
        p.setPhysicsEngineParameter(
            numSolverIterations=100,
            solverResidualThreshold=1e-7
        )
        simulation_phase = 1
    
    elif total_step == 2000:
        print("Switching to high performance mode...")
        p.setTimeStep(1./120.)
        p.setPhysicsEngineParameter(
            numSolverIterations=20,
            solverResidualThreshold=1e-4
        )
        simulation_phase = 2
    
    p.stepSimulation()
    
    # Monitor performance impact
    if total_step % 500 == 0:
        print(f"Step {total_step}, Phase {simulation_phase}")

Contact Parameter Tuning

import pybullet as p

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

# Load objects for contact testing
planeId = p.loadURDF("plane.urdf")
cubeId = p.loadURDF("cube.urdf", [0, 0, 2])

# Experiment with different contact parameters
contact_configs = [
    {"erp": 0.2, "description": "Soft contacts"},
    {"erp": 0.8, "description": "Stiff contacts"},
    {"contactBreakingThreshold": 0.001, "description": "Precise contacts"},
    {"restitutionVelocityThreshold": 0.1, "description": "Low restitution threshold"}
]

for i, config in enumerate(contact_configs):
    p.resetSimulation()
    p.setGravity(0, 0, -9.81)
    
    # Apply configuration
    p.setPhysicsEngineParameter(**{k: v for k, v in config.items() if k != "description"})
    
    # Reload objects
    planeId = p.loadURDF("plane.urdf")
    cubeId = p.loadURDF("cube.urdf", [0, 0, 2])
    
    print(f"\nTesting: {config['description']}")
    
    # Run simulation and monitor contacts
    max_force = 0
    for step in range(500):
        p.stepSimulation()
        
        contacts = p.getContactPoints(cubeId, planeId)
        if contacts:
            force = contacts[0][9]  # Normal force
            max_force = max(max_force, force)
    
    print(f"Maximum contact force: {max_force:.2f} N")

Performance Guidelines

Time Step Selection

  • 1/240s (0.0042s): High precision, complex robots, soft bodies
  • 1/120s (0.0083s): Good balance for most robotics applications
  • 1/60s (0.0167s): Fast simulation, simple rigid bodies
  • > 1/60s: Use with caution, may cause instability

Solver Iterations

  • 20-30: Fast simulation, simple scenes
  • 50: Default, good for most applications
  • 100+: High precision, complex constraints, soft bodies

Memory and Performance

  • enableFileCaching=1: Faster subsequent loads
  • deterministicOverlappingPairs=0: Faster collision detection
  • numSubSteps=1: Standard, increase for soft bodies or small time steps
  • useSplitImpulse=1: Better stability, slightly slower

Best Practices

  1. Start with defaults - PyBullet's default parameters work well for most applications
  2. Profile before optimizing - Measure performance impact of parameter changes
  3. Test stability - Ensure parameter changes don't introduce instabilities
  4. Match time step to application - Real-time applications need appropriate time steps
  5. Consider trade-offs - Accuracy vs. performance is always a balance
  6. Use presets - Start with configuration presets for your application domain
  7. Monitor solver convergence - Watch for solver warnings in complex simulations
  8. Validate physics - Test against known physical behaviors when tuning parameters

Install with Tessl CLI

npx tessl i tessl/pypi-pybullet

docs

collision-detection.md

connection-simulation.md

index.md

inverse-kinematics-dynamics.md

joint-motor-control.md

mathematical-utilities.md

object-loading.md

physics-configuration.md

rendering-visualization.md

state-management-logging.md

vr-input-handling.md

tile.json