Implementation:Farama Foundation Gymnasium Car Dynamics
| Knowledge Sources | |
|---|---|
| Domains | Reinforcement_Learning, Box2D_Environments |
| Last Updated | 2026-02-15 03:00 GMT |
Overview
Car is a top-down car physics model built on Box2D that simulates a rear-wheel-drive vehicle with four independently modeled wheels, steering, engine power, braking, and tire friction dynamics.
Description
The Car class implements a detailed top-down car dynamics simulation using the Box2D physics engine. The vehicle is composed of a multi-polygon hull body (four fixture shapes forming the car body profile) and four wheels connected to the hull via revolute joints. The front two wheels support steering via joint angle limits, while the rear two wheels provide engine drive. Each wheel tracks its own angular velocity (omega), gas input, brake state, and steering angle independently.
The physics model in the step method computes realistic tire forces each frame. For each wheel, it calculates forward and lateral velocity components, applies engine torque to rear wheels based on gas input, handles braking (including full wheel lock above 0.9 brake), and computes friction forces that are clamped to a friction limit. The friction limit varies based on whether the wheel is on a road tile (high friction) or grass (60% of normal friction). When tire forces exceed twice the friction limit, skid particles are generated for visual feedback. The wheel angular velocity is updated based on the net torque, and linear forces are applied to the wheel body through Box2D.
The car also provides a draw method for rendering the hull and wheels (with animated wheel rotation stripes) and manages a particle system for skid trace visualization. Fuel consumption is tracked via the fuel_spent attribute. The class is designed to be instantiated and controlled by the CarRacing environment rather than used standalone.
Usage
Use the Car class as the vehicle physics model within the CarRacing environment. It is instantiated during environment reset with an initial position and angle derived from the track start point. The CarRacing environment delegates steering, gas, and brake commands to the Car instance each step, and calls its step method to advance the wheel physics before the Box2D world step. It is not intended for direct use outside the CarRacing environment.
Code Reference
Source Location
- Repository: Farama_Foundation_Gymnasium
- File: gymnasium/envs/box2d/car_dynamics.py
Signature
class Car:
def __init__(
self,
world: Box2D.b2World,
init_angle: float,
init_x: float,
init_y: float,
)
Import
from gymnasium.envs.box2d.car_dynamics import Car
I/O Contract
Inputs
Constructor Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
| world | Box2D.b2World | Yes | The Box2D physics world in which to create the car bodies and joints. |
| init_angle | float | Yes | Initial orientation angle of the car in radians. |
| init_x | float | Yes | Initial x-position of the car hull in world coordinates. |
| init_y | float | Yes | Initial y-position of the car hull in world coordinates. |
Control Methods:
| Method | Parameter | Type | Description |
|---|---|---|---|
| gas(gas) | gas | float | Throttle input, clipped to [0, 1]. Applied gradually (max +0.1 per call) to rear wheels only. |
| brake(b) | b | float | Brake input in [0, 1]. Values above 0.9 lock wheels to zero rotation. |
| steer(s) | s | float | Steering target in [-1, 1]. Applied to front two wheels. Steering angle changes over time (not instant). |
| step(dt) | dt | float | Time delta in seconds. Advances wheel physics: engine torque, braking, friction, skid particles. |
Outputs
Attributes (after construction and stepping):
| Name | Type | Description |
|---|---|---|
| hull | Box2D.b2Body | The main car body. Provides position, angle, linearVelocity, and angularVelocity. |
| wheels | list[Box2D.b2Body] | Four wheel bodies: [front-left, front-right, rear-left, rear-right]. Each has omega, phase, gas, brake, steer, and tiles attributes. |
| fuel_spent | float | Cumulative fuel consumption since last reset, proportional to engine power and gas input. |
| drawlist | list[Box2D.b2Body] | Ordered list of bodies for rendering (wheels + hull). |
| particles | list[Particle] | Skid trace particles for visual rendering. Each has poly, color, ttl, and grass attributes. |
Key Methods
| Method | Description |
|---|---|
| __init__(world, init_angle, init_x, init_y) | Creates the hull from four polygon fixtures and four wheels with revolute joints. Initializes wheel state (gas, brake, steer, omega, phase). |
| gas(gas) | Sets throttle for rear wheels with gradual increase (max +0.1 per call) and immediate decrease. |
| brake(b) | Sets brake value for all four wheels. Values >= 0.9 lock wheel rotation. |
| steer(s) | Sets steering target for front two wheels. Actual joint angle changes are applied in step(). |
| step(dt) | Core physics update: computes steering joint motor speeds, determines friction limits (road vs grass), calculates engine torque and braking forces, resolves forward and lateral tire forces against friction limit, generates skid particles, and applies net forces to wheel bodies. |
| draw(surface, zoom, translation, angle, draw_particles) | Renders the car on a pygame surface with coordinate transformation. Draws skid particles, hull polygons, wheel polygons with animated rotation stripes. |
| destroy() | Removes the hull and all wheel bodies from the Box2D world. |
Physics Constants
| Constant | Value | Description |
|---|---|---|
| SIZE | 0.02 | Global scale factor for all dimensions. |
| ENGINE_POWER | 100000000 * SIZE^2 | Engine power applied to rear wheels. |
| WHEEL_MOMENT_OF_INERTIA | 4000 * SIZE^2 | Moment of inertia for wheel rotation calculations. |
| FRICTION_LIMIT | 1000000 * SIZE^2 | Maximum friction force; grass friction is 60% of this value. |
| WHEEL_R | 27 | Wheel radius (before SIZE scaling). |
| WHEEL_W | 14 | Wheel width (before SIZE scaling). |
Usage Examples
import Box2D
from gymnasium.envs.box2d.car_dynamics import Car
# Create a Box2D world (typically done by CarRacing environment)
world = Box2D.b2World((0, 0))
# Create a car at the origin facing right
car = Car(world, init_angle=0.0, init_x=0.0, init_y=0.0)
# Apply controls
car.steer(-0.3) # steer slightly left
car.gas(0.8) # apply 80% throttle
car.brake(0.0) # no braking
# Step the car physics (1/50 second timestep)
car.step(1.0 / 50.0)
# Step the Box2D world
world.Step(1.0 / 50.0, 6 * 30, 2 * 30)
# Read car state
print(f"Position: {car.hull.position}")
print(f"Angle: {car.hull.angle}")
print(f"Fuel spent: {car.fuel_spent}")
# Clean up
car.destroy()