Observation System
The observation system uses a factory pattern to provide different observation types for different use cases.
Source: gymkhana/envs/observation.py
Observation types
"rl"Standard RL observations suitable for general racing tasks.
"drift"Extended observations including vehicle slip angle, yaw rate, and other states relevant to drift control. Supports normalization.
Configuration
config = {
'observation_config': {'type': 'drift'},
'lookahead_n_points': 10, # Number of lookahead curvature/width points (default: 10)
'lookahead_ds': 0.3, # Spacing between lookahead points in metres (default: 0.3)
'sparse_width_obs': False, # False: all width values, True: only 1st and last
'normalize_obs': True, # Enable observation normalization (only for 'drift' type)
}
Lookahead observations
The observation can include curvature and track width samples at points ahead of the vehicle along the track centerline. The number of points and their spacing are configurable.
When sparse_width_obs is True, only the first and last lookahead width values are included in the observation. This is useful when track width varies very little.
Normalization
When normalize_obs is True, observation values are scaled to a bounded range. Normalization bounds are defined in the codebase and can be tuned by enabling record_obs_min_max in the config to record actual min/max values during training runs.
API reference
- gymkhana.envs.observation.sample_lookahead_curvatures(track, current_s: float, n_points: int, ds: float) ndarray
Sample N curvature values ahead of vehicle at uniform intervals along centerline.
Sampling starts at ds meters ahead (not at current position) and proceeds forward. For closed tracks, sampling wraps around using modulo arithmetic.
Parameters
- trackTrack
Track object with centerline (must not be None)
- current_sfloat
Current arc length position on centerline (meters)
- n_pointsint
Number of lookahead points to sample (default 10)
- dsfloat
Spacing between points in meters (default 0.3m = 30cm)
Returns
- curvaturesnp.ndarray (n_points,)
Curvature at each lookahead point (1/m)
Raises
- ValueError
If track, centerline, or spline is None/invalid
- gymkhana.envs.observation.sample_lookahead_curvatures_fast(track, current_s: float, n_points: int = 10, ds: float = 0.3) ndarray
High-performance version of sample_lookahead_curvatures using numba JIT compilation.
This function provides ~20x speedup for real-time applications by using numba to compile the curvature sampling loop. Use this when performance is critical (e.g., high-frequency control loops at 100Hz+).
Parameters
- trackTrack
Track object with centerline (must not be None)
- current_sfloat
Current arc length position on centerline (meters)
- n_pointsint
Number of lookahead points to sample (default 10)
- dsfloat
Spacing between points in meters (default 0.3m = 30cm)
Returns
- curvaturesnp.ndarray (n_points,)
Curvature at each lookahead point (1/m)
Raises
- ValueError
If track, centerline, or spline is None/invalid
- gymkhana.envs.observation.sample_lookahead_widths(track, current_s: float, n_points: int, ds: float) ndarray
Sample N track width values ahead of vehicle at uniform intervals along centerline.
Sampling starts at ds meters ahead (not at current position) and proceeds forward. For closed tracks, sampling wraps around using modulo arithmetic.
Parameters
- trackTrack
Track object with centerline (must not be None)
- current_sfloat
Current arc length position on centerline (meters)
- n_pointsint
Number of lookahead points to sample (default 10)
- dsfloat
Spacing between points in meters (default 0.3m = 30cm)
Returns
- widthsnp.ndarray (n_points,)
Total track width (w_left + w_right) at each lookahead point (meters)
Raises
- ValueError
If track, centerline, or width data is None/invalid
- gymkhana.envs.observation.sample_lookahead_widths_fast(track, current_s: float, n_points: int = 10, ds: float = 0.3) ndarray
High-performance version of sample_lookahead_widths using numba JIT compilation.
This function provides ~1.2x speedup for real-time applications by using numba to compile the width sampling loop. Use this when performance is critical (e.g., high-frequency control loops at 100Hz+).
Parameters
- trackTrack
Track object with centerline (must not be None)
- current_sfloat
Current arc length position on centerline (meters)
- n_pointsint
Number of lookahead points to sample (default 10)
- dsfloat
Spacing between points in meters (default 0.3m = 30cm)
Returns
- widthsnp.ndarray (n_points,)
Total track width (w_left + w_right) at each lookahead point (meters)
Raises
- ValueError
If track, centerline, or width data is None/invalid
- class gymkhana.envs.observation.Observation(env)
Abstract class for observations. Each observation must implement the space and observe methods.
- Parameters:
env – The environment.
vehicle_id – The id of the observer vehicle.
kwargs – Additional arguments.
- abstractmethod space()
Defines the observation space structure for the gym env :return gym.spaces object that desribes shape, data types, and observation bounds
- abstractmethod observe()
Generated the observation data at each time step :return current observation values as np array or dict
- class gymkhana.envs.observation.OriginalObservation(env)
- space()
Defines the observation space structure for the gym env :return gym.spaces object that desribes shape, data types, and observation bounds
- observe()
Generated the observation data at each time step :return current observation values as np array or dict
- class gymkhana.envs.observation.FeaturesObservation(env, features: List[str])
- space()
Defines the observation space structure for the gym env :return gym.spaces object that desribes shape, data types, and observation bounds
- observe()
Generated the observation data at each time step :return current observation values as np array or dict
- class gymkhana.envs.observation.VectorObservation(env, features: List[str])
- space()
Defines the observation space structure for the gym env :return gym.spaces object that desribes shape, data types, and observation bounds
- observe()
Generated the observation data at each time step :return current observation values as np array or dict
- gymkhana.envs.observation.observation_factory(env, type: str | None, **kwargs) Observation