Dynamic Models

Gym-Khana provides four vehicle dynamics models of increasing complexity. All use numba JIT compilation for real-time performance.

Source: gymkhana/envs/dynamic_models/

KS — Kinematic Single Track

gymkhana/envs/dynamic_models/kinematic.py

Simplest model using pure kinematics without tire forces. Suitable for low-speed scenarios where tire slip is negligible.

ST — Single Track

gymkhana/envs/dynamic_models/single_track.py

Single-track dynamics model with basic tire modeling. Models lateral dynamics but without an explicit tire force model.

MB — Multi-Body

gymkhana/envs/dynamic_models/multi_body/

Most detailed model with full tire modeling and multi-body dynamics. Provides the highest fidelity but parameters are only available for a full-scale vehicle (not 1/10 scale).

STD — Single Track Drift

gymkhana/envs/dynamic_models/single_track_drift/

Single-track dynamics with PAC2002 (Pacejka Magic Formula) tire model. Recommended for RL drift training. This model captures realistic tire force saturation and slip behavior needed for drifting.

Use with:

config = {
    'model': 'std',
    'control_input': ['accl', 'steering_angle'],
    'params': GKEnv.f1tenth_std_vehicle_params(),
}

Vehicle parameters

The dynamic model’s physical parameters include:

  • mu: surface friction coefficient

  • C_Sf / C_Sr: cornering stiffness coefficient, front/rear [1/rad]

  • lf / lr: distance from CG to front/rear axle [m]

  • h: height of center of gravity [m]

  • m: total vehicle mass [kg]

  • I: moment of inertia about z axis [kg m^2]

  • s_min / s_max: steering angle constraints [rad]

  • sv_min / sv_max: steering velocity constraints [rad/s]

  • v_switch: velocity at which acceleration can no longer create wheel spin [m/s]

  • a_max: maximum longitudinal acceleration [m/s^2]

  • v_min / v_max: longitudinal velocity bounds [m/s]

  • width / length: vehicle dimensions [m]

Parameters can be passed via the params key in the config dict, or updated at runtime with env.update_params().

API reference

gymkhana.envs.dynamic_models.kinematic.vehicle_dynamics_ks(x: ndarray, u_init: ndarray, params: dict)

Single Track Kinematic Vehicle Dynamics. Follows https://gitlab.lrz.de/tum-cps/commonroad-vehicle-models/-/blob/master/vehicleModels_commonRoad.pdf, section 5

Args:
x (numpy.ndarray (5, )): vehicle state vector (x0, x1, x2, x3, x4)

x0: x position in global coordinates x1: y position in global coordinates x2: steering angle of front wheels x3: velocity in x direction x4: yaw angle

u (numpy.ndarray (2, )): control input vector (u1, u2)

u1: steering angle velocity of front wheels u2: longitudinal acceleration

params (dict): dictionary containing the following parameters:

mu (float): friction coefficient C_Sf (float): cornering stiffness of front wheels C_Sr (float): cornering stiffness of rear wheels lf (float): distance from center of gravity to front axle lr (float): distance from center of gravity to rear axle h (float): height of center of gravity m (float): mass of vehicle I (float): moment of inertia of vehicle, about Z axis s_min (float): minimum steering angle s_max (float): maximum steering angle sv_min (float): minimum steering velocity sv_max (float): maximum steering velocity v_switch (float): velocity above which the acceleration is no longer able to create wheel slip a_max (float): maximum allowed acceleration v_min (float): minimum allowed velocity v_max (float): maximum allowed velocity

Returns:

f (numpy.ndarray): right hand side of differential equations

gymkhana.envs.dynamic_models.kinematic.vehicle_dynamics_ks_cog(x: ndarray, u_init: ndarray, params: dict)

Single Track Kinematic Vehicle Dynamics. Follows https://gitlab.lrz.de/tum-cps/commonroad-vehicle-models/-/blob/master/vehicleModels_commonRoad.pdf, section 5

Args:
x (numpy.ndarray (5, )): vehicle state vector (x0, x1, x2, x3, x4)

x0: x position in global coordinates x1: y position in global coordinates x2: steering angle of front wheels x3: velocity in x direction x4: yaw angle

u (numpy.ndarray (2, )): control input vector (u1, u2)

u1: steering angle velocity of front wheels u2: longitudinal acceleration

params (dict): dictionary containing the following parameters:

mu (float): friction coefficient C_Sf (float): cornering stiffness of front wheels C_Sr (float): cornering stiffness of rear wheels lf (float): distance from center of gravity to front axle lr (float): distance from center of gravity to rear axle h (float): height of center of gravity m (float): mass of vehicle I (float): moment of inertia of vehicle, about Z axis s_min (float): minimum steering angle s_max (float): maximum steering angle sv_min (float): minimum steering velocity sv_max (float): maximum steering velocity v_switch (float): velocity above which the acceleration is no longer able to create wheel slip a_max (float): maximum allowed acceleration v_min (float): minimum allowed velocity v_max (float): maximum allowed velocity

Returns:

f (numpy.ndarray): right hand side of differential equations

gymkhana.envs.dynamic_models.kinematic.get_standardized_state_ks(x: ndarray) dict

[X,Y,DELTA,V_X, V_Y,YAW,YAW_RATE,SLIP]

gymkhana.envs.dynamic_models.single_track.vehicle_dynamics_st(x: ndarray, u_init: ndarray, params: dict)

Single Track Vehicle Dynamics. From https://gitlab.lrz.de/tum-cps/commonroad-vehicle-models/-/blob/master/vehicleModels_commonRoad.pdf, section 7

Difference from commonroad imp (commonroad/vehiclemodels/vehicle_dynamics_st.py): 1. Framework conversion (Python classes -> NumPy/Numba)

  1. parameters are stored in a params dict instead of a p object

  2. state vector x stored as a np array instead of a list, and gives them clearer names

  1. Kinematic threshold change
    1. switch to kinematic/dynamics happens for V < 0.5, instead of x[3] < 0.1

  2. slip angle derivatives (BETA_HAT, BETA_DOT) are computed differently from commonroad (d_beta, dd_psi)
    1. All the BETA_HAT variable is doing is performing a modulus operation to bound the value

  3. Dynamic model equations
    1. these are the same but restructured

    2. glr and glf are precomputed

    3. Readability is improved

    4. np array returned instead of list

  4. Added method get_standardized_state_st to extract state info

  5. Math libraries - all math function calls are replaced with np function calls (for ex. np.cos replaces math.cos)

    Args:
    x (numpy.ndarray (7, )): vehicle state vector (x0, x1, x2, x3, x4, x5, x6)

    x0: x position in global coordinates x1: y position in global coordinates x2: steering angle of front wheels x3: velocity in x direction x4:yaw angle x5: yaw rate x6: slip angle at vehicle center

    u (numpy.ndarray (2, )): control input vector (u1, u2)

    u1: steering angle velocity of front wheels u2: longitudinal acceleration

    params (dict): dictionary containing the following parameters:

    mu (float): friction coefficient C_Sf (float): cornering stiffness of front wheels C_Sr (float): cornering stiffness of rear wheels lf (float): distance from center of gravity to front axle lr (float): distance from center of gravity to rear axle h (float): height of center of gravity m (float): mass of vehicle I (float): moment of inertia of vehicle, about Z axis s_min (float): minimum steering angle s_max (float): maximum steering angle sv_min (float): minimum steering velocity sv_max (float): maximum steering velocity v_switch (float): velocity above which the acceleration is no longer able to create wheel spin a_max (float): maximum allowed acceleration v_min (float): minimum allowed velocity v_max (float): maximum allowed velocity

    Returns:

    f (numpy.ndarray): right hand side of differential equations

gymkhana.envs.dynamic_models.single_track.get_standardized_state_st(x: ndarray) dict

[X,Y,DELTA,V_X, V_Y,YAW,YAW_RATE,SLIP]

gymkhana.envs.dynamic_models.multi_body.multi_body.vehicle_dynamics_mb(x: ndarray, u_init: ndarray, params: dict)

vehicleDynamics_mb - multi-body vehicle dynamics based on the DoT (department of transportation) vehicle dynamics reference point: center of mass

Syntax:

f = vehicleDynamics_mb(x,u,p)

Inputs:
param x:

vehicle state vector

param uInit:

vehicle input vector

param params:

vehicle parameter vector

Outputs:
return f:

right-hand side of differential equations

gymkhana.envs.dynamic_models.multi_body.multi_body.get_standardized_state_mb(x: ndarray) dict

[X,Y,DELTA,V_X, V_Y,YAW,YAW_RATE,SLIP]

gymkhana.envs.dynamic_models.single_track_drift.single_track_drift.vehicle_dynamics_std(x: ndarray, u_init: ndarray, params: dict)

Single Track Drift model. From: https://gitlab.lrz.de/tum-cps/commonroad-vehicle-models/-/blob/master/PYTHON/vehiclemodels/vehicle_dynamics_std.py?ref_type=heads

Syntax:

f = vehicle_dynamics_std(x,u,p)

Inputs:
param x:

(numpy.ndarray (9,)): vehicle state vector (x0, x1, x2, x3, x4, x5, x6, x7, x8) x[0]: x position in Cartesian global coordinates x[1]: y position in Cartesian global coordinates x[2]: steering angle of front wheels x[3]: velocity in x direction x[4]: yaw angle in Cartesian global coordinates x[5]: yaw rate x[6]: slip angle at vehicle center x[7]: angular speed of the front wheel x[8]: angular speed of the rear wheel

param u_init:

(numpy.ndarray (2,)): control input vector (u1, u2) u_init[0]: steering angle velocity of front wheels u_init[1]: longitudinal acceleration

param params:

(dict): dictionary containing necessary parameters:

Outputs:
return f:

(numpy.ndarray): right hand side of differential equations

Author: Teodor Ilie Written: 18-October-2025

gymkhana.envs.dynamic_models.single_track_drift.single_track_drift.get_standardized_state_std(x: ndarray) dict
The standard state is fetched to use for calculating observations.
Args:

x: current state vector

Returns:

Return the standard state for the STD model [

x - global coords y - global coords delt - steering angle v_x - velocity in x v_y - velocity in y yaw - yaw phi yaw_rate - phi dot slip - beta

]