logo

Configuration

All configuration is passed through the config dictionary to gym.make().

Default configurations

Default configurations for RL training and testing are in train/config/env_config.py, with parameters loaded from:

  • train/config/rl_config.yaml — RL hyperparameters (n_envs, learning rate, batch size, etc.)

  • train/config/gym_config.yaml — Gym environment parameters (map, model, timestep, etc.)

Convenience functions return ready-made configs:

  • get_drift_test_config() / get_drift_train_config()

  • get_recovery_test_config() / get_recovery_train_config()

Vehicle model and control

env = gym.make('gymkhana:gymkhana-v0', config={
    'model': 'std',                              # STD for drifting with PAC2002 tire model
    'params': GKEnv.f1tenth_std_vehicle_params(),  # Drift parameters for 1/10 scale
})

Note

Available models: ks (kinematic), st (single-track), mb (multi-body), std (single-track drift). Use std for drift training. See Dynamic Models for details.

For action space configuration (control_input, normalize_act), see Action System.

Training mode

Set training_mode to define the training goal. This modifies the reset, initialization, track, and reward settings:

  • "race" (default) — used by train/ppo_race.py for training racing policies

  • "recover" — used by train/ppo_recover.py to train policies for stabilizing an out-of-control vehicle

Track direction

Set track_direction to control which direction to drive around the track:

  • "normal" (default) — follow waypoint direction (may be CW or CCW depending on the map)

  • "reverse" — drive in the opposite direction

  • "random" — randomly choose direction at each reset (50/50), useful for learning both left and right cornering

Observation configuration

config = {
    'observation_config': {'type': 'drift'},  # or 'rl' for standard observations
    'lookahead_n_points': 10,                  # Number of lookahead points (default: 10)
    'lookahead_ds': 0.3,                       # Spacing between points in meters (default: 0.3m)
    'sparse_width_obs': False,                 # False: all widths, True: only 1st and last
    'normalize_obs': True,                     # Enable observation normalization (only 'drift' obs)
}

See Observation System for details.

Collision and safety

config = {
    'predictive_collision': True,   # True: TTC collision checking, False: Frenet-based
    'wall_deflection': False,       # False: edges are boundaries, True: edges cause collision
}

Note that predictive_collision also modifies the reward function.

Reward configuration

config = {
    'progress_gain': 1.0,          # Gain multiplier for forward progress reward (>= 1)
    'out_of_bounds_penalty': ...,   # Penalty for driving off the track boundary
    'negative_vel_penalty': ...,    # Penalty for driving backward
    'max_episode_steps': ...,       # Maximum number of episode steps
}

Reset options

Vehicles can be initialized at specific configurations via env.reset(options=...).

Poses — reset agents at a specific [x, y, yaw] in Cartesian coordinates:

# Single agent
poses = np.array([[x, y, yaw]])
env.reset(options={"poses": poses})

# Multiple agents
poses = np.array([[x1, y1, yaw1],
                  [x2, y2, yaw2]])
env.reset(options={"poses": poses})

States — reset agents to a full 7-d state (only for model='std'):

# [x, y, delta, v, yaw, yaw_rate, slip_angle]
states = np.array([[x, y, delta, v, yaw, yaw_rate, slip_angle]])
env.reset(options={"states": states})

# Front & rear angular wheel velocities are automatically initialized
# to form the full 9-d state for the STD model type

Only one of poses or states can be used per reset call. To use Frenet coordinates, convert first using frenet_to_cartesian() in gymkhana/envs/track/track.py.

Debugging and visualization

config = {
    'render_mode': 'human',                    # Enable visualization window
    'render_track_lines': True,                # Centerline (green) and raceline (red)
    'render_lookahead_curvatures': True,       # Lookahead curvature points (yellow)
    'render_arc_length_annotations': True,     # Arc-length points along centerline (orange)
    'arc_length_annotation_interval': 2.0,     # Spacing in metres (default: 2.0)
    'debug_frenet_projection': True,           # Visualize Frenet coordinate accuracy
    'record_obs_min_max': True,                # Record min/max obs for normalization tuning
}

Debug with breakpoints by looping through environment steps (see tests/drift_debug.py).

Control debug panel

Set show_ctr_debug: True in gymkhana/envs/rendering/rendering.yaml to enable a real-time control debug panel below the map (PyQt6 renderer only). The panel displays:

  • Actual vehicle state (white text): current steering angle (delta) and longitudinal velocity (v_x)

  • Control commands (colour-coded text): raw steering command in blue, throttle command in green, each with their bounds

  • Zero-centered bar gauges: two horizontal bars (one per command) spanning the full command range, with the fill extending from zero toward the current value

The panel tracks whichever agent the camera is following (switched via mouse click), defaulting to the ego agent in map view. Disabled by default to avoid overhead during RL training.

Observation debug overlay

Set show_obs_debug: True in gymkhana/envs/rendering/rendering.yaml to overlay all observation values on top of the map in the top-left corner (PyQt6 renderer only). The overlay displays:

  • Feature names and values: each observation feature as a key-value pair (e.g., linear_vel_x: 2.3451)

  • Array summaries: large arrays like LiDAR scans show count, min, max, and mean; small arrays (e.g., lookahead curvatures) show all values

  • Normalization indicator: shows [norm: on] when observation normalization is active; values are always displayed in raw physical units regardless of normalization

Works with all observation types (OriginalObservation, FeaturesObservation, VectorObservation). For multi-agent environments, the overlay shows the followed agent’s observations. Disabled by default to avoid overhead during RL training.

Custom maps

Maps follow the ROS map convention: a .yaml metadata file and a single-channel black-and-white image (black = obstacles, white = free space).

The resolution field (m/pixel) and the first two values of origin (bottom-left corner in world coordinates) are used by the environment. Place both files in the same directory with the same base name, then:

env = gym.make('gymkhana:gymkhana-v0', config={
    'map': '/your/path/to/map',  # without extension
    'map_ext': '.png',
})

Maps are managed through a two-tier system:

To update the maps submodule: git pull --recurse-submodules