From 2033969bffa9cfb6e8cb43ad690a90eeba0e298f Mon Sep 17 00:00:00 2001 From: Eugene Vinitsky Date: Wed, 3 Jun 2026 19:26:57 +0000 Subject: [PATCH] Optional ego-size inflation in control_sdc_only obs Add env.ego_size_inflation (float fraction, default 0.0). When > 0 and control_mode == control_sdc_only, the SDC's own perceived length/width in its ego observation are scaled by (1 + ego_size_inflation); set 0.05 for +5%. Observation-only: actual sim_length/sim_width used for dynamics, collision, partner observations and rendering are unchanged. No-op in control_vehicles / control_agents / control_wosac. Plumbed through binding.c, drive.py (kwarg + attribute + C kwargs) and drive.ini (default 0.0, documented). Co-Authored-By: Claude Opus 4.8 --- pufferlib/config/ocean/drive.ini | 3 +++ pufferlib/ocean/drive/binding.c | 1 + pufferlib/ocean/drive/drive.h | 17 +++++++++++++++-- pufferlib/ocean/drive/drive.py | 3 +++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/pufferlib/config/ocean/drive.ini b/pufferlib/config/ocean/drive.ini index 6b01fa5e97..360a3d09f8 100644 --- a/pufferlib/config/ocean/drive.ini +++ b/pufferlib/config/ocean/drive.ini @@ -136,6 +136,9 @@ obs_norm_goal_offset_m = 120.0 obs_norm_xy_offset_m = 120.0 obs_norm_veh_length_m = 15.0 obs_norm_veh_width_m = 10.0 +# SDC perceives its own size inflated by this fraction in control_sdc_only obs +# (0 = off, 0.05 = +5%). Observation-only; sim dynamics/collision unchanged. +ego_size_inflation = 0.0 obs_norm_road_seg_length_m = 10.0 obs_norm_road_seg_width_m = 5.0 ; --- Observation ranges (meters, ego frame) --- diff --git a/pufferlib/ocean/drive/binding.c b/pufferlib/ocean/drive/binding.c index afc952acca..ac9530b1c3 100644 --- a/pufferlib/ocean/drive/binding.c +++ b/pufferlib/ocean/drive/binding.c @@ -2006,6 +2006,7 @@ static int my_init(Env *env, PyObject *args, PyObject *kwargs) { env->obs_norm_xy_offset_m = (float) unpack(kwargs, "obs_norm_xy_offset_m"); env->obs_norm_veh_length_m = (float) unpack(kwargs, "obs_norm_veh_length_m"); env->obs_norm_veh_width_m = (float) unpack(kwargs, "obs_norm_veh_width_m"); + env->ego_size_inflation = (float) unpack(kwargs, "ego_size_inflation"); env->obs_norm_road_seg_length_m = (float) unpack(kwargs, "obs_norm_road_seg_length_m"); env->obs_norm_road_seg_width_m = (float) unpack(kwargs, "obs_norm_road_seg_width_m"); env->obs_range_traffic_control_m = (float) unpack(kwargs, "obs_range_traffic_control_m"); diff --git a/pufferlib/ocean/drive/drive.h b/pufferlib/ocean/drive/drive.h index 7c89c9dc02..3c2e8252c5 100644 --- a/pufferlib/ocean/drive/drive.h +++ b/pufferlib/ocean/drive/drive.h @@ -455,6 +455,10 @@ struct Drive { float obs_norm_xy_offset_m; float obs_norm_veh_length_m; float obs_norm_veh_width_m; + // Fraction by which the SDC's own perceived length/width are inflated in its + // ego observation (control_sdc_only only). 0 = off; 0.05 = perceive +5%. + // Observation-only: actual sim dimensions (dynamics, collision) are unchanged. + float ego_size_inflation; float obs_norm_road_seg_length_m; float obs_norm_road_seg_width_m; float obs_range_traffic_control_m; @@ -4587,9 +4591,18 @@ static void compute_rewards(Drive *env, int i) { } static int write_ego_obs(Drive *env, Agent *ego, float *obs, int obs_idx) { + // Optionally inflate the SDC's perceived size in its own observation only + // (control_sdc_only). Sim dimensions used for dynamics/collision are untouched. + float perceived_width = ego->sim_width; + float perceived_length = ego->sim_length; + if (env->ego_size_inflation > 0.0f && env->control_mode == CONTROL_SDC_ONLY) { + perceived_width *= (1.0f + env->ego_size_inflation); + perceived_length *= (1.0f + env->ego_size_inflation); + } + obs[obs_idx++] = ego->sim_speed_signed / MAX_SPEED; - obs[obs_idx++] = ego->sim_width / env->obs_norm_veh_width_m; - obs[obs_idx++] = ego->sim_length / env->obs_norm_veh_length_m; + obs[obs_idx++] = perceived_width / env->obs_norm_veh_width_m; + obs[obs_idx++] = perceived_length / env->obs_norm_veh_length_m; obs[obs_idx++] = ego->steering_angle / STEERING_LIMIT; obs[obs_idx++] = ego->a_long / fabsf(ACCEL_LONG_LIMIT[0]); obs[obs_idx++] = ego->a_lat / ACCEL_LAT_LIMIT[1]; diff --git a/pufferlib/ocean/drive/drive.py b/pufferlib/ocean/drive/drive.py index 61da6c8d10..be0f5082b0 100644 --- a/pufferlib/ocean/drive/drive.py +++ b/pufferlib/ocean/drive/drive.py @@ -96,6 +96,7 @@ def __init__( obs_norm_xy_offset_m=100.0, obs_norm_veh_length_m=15.0, obs_norm_veh_width_m=10.0, + ego_size_inflation=0.0, obs_norm_road_seg_length_m=5.0, obs_norm_road_seg_width_m=5.0, obs_range_traffic_control_m=100.0, @@ -190,6 +191,7 @@ def __init__( self.obs_norm_xy_offset_m = float(obs_norm_xy_offset_m) self.obs_norm_veh_length_m = float(obs_norm_veh_length_m) self.obs_norm_veh_width_m = float(obs_norm_veh_width_m) + self.ego_size_inflation = float(ego_size_inflation) self.obs_norm_road_seg_length_m = float(obs_norm_road_seg_length_m) self.obs_norm_road_seg_width_m = float(obs_norm_road_seg_width_m) self.obs_range_traffic_control_m = float(obs_range_traffic_control_m) @@ -462,6 +464,7 @@ def _env_init_kwargs(self, map_file, max_agents): "obs_norm_xy_offset_m": self.obs_norm_xy_offset_m, "obs_norm_veh_length_m": self.obs_norm_veh_length_m, "obs_norm_veh_width_m": self.obs_norm_veh_width_m, + "ego_size_inflation": self.ego_size_inflation, "obs_norm_road_seg_length_m": self.obs_norm_road_seg_length_m, "obs_norm_road_seg_width_m": self.obs_norm_road_seg_width_m, "obs_range_traffic_control_m": self.obs_range_traffic_control_m,