Dynamic Models

Gym-Khana provides five 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.

STP — Single Track Pacejka

gymkhana/envs/dynamic_models/single_track_pacejka/

Dynamic single-track bicycle with a lateral-only Pacejka Magic Formula tire model (no longitudinal slip dynamics). Ported from the ForzaETH f110-simulator (STDKinematics::update_pacejka) and adjusted for this simulator. Shares ST’s 7-element state layout, so it slots in wherever ST is used.

Use with:

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

The drift_st observation type is supported on both the st and stp models.

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(),
}

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).

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

Kinematic Single Track (KS) vehicle dynamics model.

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

Compute Kinematic Single Track vehicle dynamics.

Reference: CommonRoad vehicle models, section 5.

Parameters:
  • x – State vector of shape (5,): [x_pos, y_pos, steering_angle, velocity, yaw_angle].

  • u_init – Control input [steering_velocity, acceleration].

  • paramsgymkhana.envs.params.VehicleParams NamedTuple.

Returns:

Time derivatives of the state vector, shape (5,).

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

Compute Kinematic Single Track dynamics referenced at the centre of gravity.

Unlike vehicle_dynamics_ks() (which references the rear axle), this variant computes position derivatives at the vehicle’s centre of gravity by incorporating the kinematic slip angle beta. Used by the STD and STP models for the low-speed kinematic blending regime.

Reference: CommonRoad vehicle models, section 5.

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

Extract standardized state dict from KS model state vector.

Parameters:

x – KS state vector [x_pos, y_pos, steering_angle, velocity, yaw_angle].

Returns:

x, y, delta, v_x, v_y, yaw, yaw_rate, slip. v_y, yaw_rate, and slip are zero (kinematic model).

Return type:

Dict with keys

Single Track (ST) vehicle dynamics model.

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

Compute Single Track vehicle dynamics.

Reference: CommonRoad vehicle models, section 7.

Parameters:
  • x – State vector of shape (7,): [x_pos, y_pos, steering_angle, velocity, yaw_angle, yaw_rate, slip_angle].

  • u_init – Control input [steering_velocity, acceleration].

  • paramsgymkhana.envs.params.VehicleParams NamedTuple.

Returns:

Time derivatives of the state vector, shape (7,).

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

Extract standardized state dict from ST model state vector.

Parameters:

x – ST state vector [x_pos, y_pos, steering_angle, velocity, yaw_angle, yaw_rate, slip_angle].

Returns:

x, y, delta, v_x, v_y, yaw, yaw_rate, slip.

Return type:

Dict with keys

Single Track Pacejka (STP) vehicle dynamics model.

Dynamic single-track bicycle with a Pacejka Magic Formula lateral tire model (no longitudinal slip dynamics). Ported from f110-simulator, and adjusted for this simulator. For the ref, see STDKinematics::update_pacejka (std_kinematics.cpp). https://github.com/ForzaETH/f1tenth_simulator

Deviations from the C++ original:

  • State uses (V, beta) instead of (v_x, v_y); body-frame derivatives are chain-ruled into (V_dot, beta_dot).

  • Returns derivatives only (gymkhana’s RK4 integrates externally), so the low-speed kinematic blend mixes derivatives, not post-integrated states.

  • Constraints applied inside f.

  • Slip-angle sign flipped (gymkhana convention); F_y is negated to compensate since Pacejka is odd in alpha.

  • Blend thresholds match the f110 reference (v_s=3.0, v_b=1.0, v_min_blend=1.0) and are gated on V rather than v_x; the hard w_std=0 clamp below v_min is replaced by a sharper tanh plus zeroing alpha and beta_dot below v_min_blend. Thresholds are overridable via VehicleParams fields blend_v_s, blend_v_b, blend_v_min (used by parity tests against the f110 ref).

State extraction: STP shares the ST 7-element state layout, so the dispatch in dynamic_models/__init__.py reuses ST’s get_standardized_state_st for STP rather than defining a separate function here.

gymkhana.envs.dynamic_models.single_track_pacejka.single_track_pacejka.vehicle_dynamics_stp(x: ndarray, u_init: ndarray, params) ndarray

Compute Single Track Pacejka vehicle dynamics.

Parameters:
  • x – State vector of shape (7,): [x_pos, y_pos, steering_angle, velocity, yaw_angle, yaw_rate, slip_angle].

  • u_init – Control input [steering_velocity, acceleration].

  • paramsgymkhana.envs.params.VehicleParams NamedTuple.

Returns:

Time derivatives of the state vector, shape (7,).

Single Track Drift (STD) vehicle dynamics model with PAC2002 tire model.

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

Compute Single Track Drift vehicle dynamics.

Extends the ST model with a PAC2002 (Pacejka Magic Formula) tire model to capture tire force saturation and slip needed for drifting.

Reference: CommonRoad STD model (vehicle_dynamics_std.py).

Author: Teodor Ilie (18-October-2025).

Parameters:
  • x – State vector of shape (9,): [x_pos, y_pos, steering_angle, velocity, yaw_angle, yaw_rate, slip_angle, front_wheel_omega, rear_wheel_omega].

  • u_init – Control input [steering_velocity, acceleration].

  • paramsgymkhana.envs.params.VehicleParams NamedTuple.

Returns:

Time derivatives of the state vector, shape (9,).

gymkhana.envs.dynamic_models.single_track_drift.single_track_drift.get_standardized_state_std(x: ndarray) dict

Extract standardized state dict from STD model state vector.

Parameters:

x – STD state vector [x_pos, y_pos, steering_angle, velocity, yaw_angle, yaw_rate, slip_angle, omega_front, omega_rear].

Returns:

x, y, delta, v_x, v_y, yaw, yaw_rate, slip.

Return type:

Dict with keys

Multi-Body (MB) vehicle dynamics model.

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

Compute Multi-Body vehicle dynamics.

DoT (Department of Transportation) based multi-body model. Reference point is the center of mass. State vector is 29-dimensional; use DynamicModel.get_initial_state() to initialize correctly.

Parameters:
  • x – State vector of shape (29,) (see source for component index map).

  • u_init – Control input [steering_velocity, acceleration].

  • params – Vehicle parameters dict (see gymkhana.envs.dynamic_models).

Returns:

Time derivatives of the state vector, shape (29,).

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]