6 bernhard dev - #580
Conversation
env.goal_source=route \
env.max_goal_spacing=60 \
…ed on the date and I do not need to touch the script anymore.,
| # Replay-mode agents flagged mark_as_expert are log-replayed (1) or treated like any other agent (0) | ||
| replay_expert_agents: 1 |
There was a problem hiding this comment.
duplicated config
you should be able to do the same thing with
Controller used by non-SDC vehicles.
options: "static", "policy", "replay", "idm"
non_sdc_controller: policy
Controller used by non-vehicle agents. "auto" follows non_sdc_controller unless it is "idm", then it uses "replay".
options: "auto", "static", "policy", "replay", "idm"
non_vehicle_controller: auto
in replay
There was a problem hiding this comment.
So I only use replay_expert_agents: 0
for nuPlan and CARLA
Claude claims the 1 branch is necessary for compatibility with WOMD, but I never used WOMD, so idk.
The controllers are category-wide, whereas this flag uses the expert/non-expert flag from the dataset
I would keep it if it doesn't bother.
There was a problem hiding this comment.
I see, I quoted the wrong config then
You could add a new option to control_mode like control_all_vehicles that would actually control all valid cars, enforcing controlling the mark_as_expert ones
Ideally we don't want to create one config variable for every behavior we rather try to merge into existing one when possible
| PyObject *tuple = PyTuple_New(4); | ||
| PyTuple_SetItem(tuple, 0, agent_offsets); | ||
| PyTuple_SetItem(tuple, 1, map_ids_list); | ||
| PyTuple_SetItem(tuple, 2, PyLong_FromLong(env_count)); | ||
| PyTuple_SetItem(tuple, 3, PyLong_FromLong(env_count)); | ||
| return tuple; | ||
| } |
| PyObject *tuple = PyTuple_New(4); | ||
| PyTuple_SetItem(tuple, 0, agent_offsets); | ||
| PyTuple_SetItem(tuple, 1, map_ids_list); | ||
| PyTuple_SetItem(tuple, 2, PyLong_FromLong(env_count)); | ||
| PyTuple_SetItem(tuple, 3, PyLong_FromLong(env_count)); | ||
| return tuple; | ||
| } |
There was a problem hiding this comment.
Slot 3 is maps_consumed, Slot 2 is num_envs. Both are used in the code. We could also set the equivalence elsewhere I guess?
| // Per-episode perturbation rates: uniform in [0, configured max] | ||
| env->episode_partner_blindness_prob = sample_uniform(&env->rng_state, 0.0f, env->partner_blindness_prob); | ||
| env->episode_phantom_braking_prob = sample_uniform(&env->rng_state, 0.0f, env->phantom_braking_prob); |
There was a problem hiding this comment.
why do we want a probability for all agents inside an episode vs having a probality per agent ?
There was a problem hiding this comment.
To match the gigaflow paper which have an up to 5% number of phantom brakers. That is the total number of phatom brakers in an episode.
The individual phantom braker still has a probability for it to trigger.
We want agents that experience clean episodes and agents that experience crazy epsiodes I think.
Having it per agent would mean that on average all scenarios look the same due to many draws?
There was a problem hiding this comment.
Ok I understand. In my comprehension of the paper, the "Up to 10% of agents" refers to all the agents batch-wise, so not per episode
I have no idea which one is correct
There was a problem hiding this comment.
yeah, we can ask eugene when he is back. The uniform distribution I use is also an assumption. Though I think this change did help to reduce the rear end collisions, so I would keep it unless eugene says he has a better solution.
| static bool walk_to_next_goal( | ||
| Drive *env, | ||
| const int *route, | ||
| int route_length, | ||
| int cursor_idx, | ||
| float s_on_lane, | ||
| float spacing_meters, | ||
| float prev_heading, | ||
| float *out_x, | ||
| float *out_y, | ||
| float *out_z, | ||
| int *out_lane_idx, | ||
| int *out_cursor_idx, | ||
| float *out_s_on_lane, | ||
| float *out_heading) { | ||
| // One goal step forward. In free-roam mode with goal_heading_max_deg > 0, re-samples the spacing until the | ||
| // landed lane heading is within that angle of prev_heading; accepts the last attempt if none qualifies. | ||
| bool constrain_heading = route == NULL && env->goal_heading_max_deg > 0.0f; | ||
| float max_heading_delta_rad = env->goal_heading_max_deg * (float) M_PI / 180.0f; | ||
| for (int attempt_idx = 0; attempt_idx < GOAL_HEADING_MAX_ATTEMPTS; attempt_idx++) { | ||
| if (attempt_idx > 0) { | ||
| spacing_meters = sample_uniform(&env->rng_state, env->min_goal_spacing, env->max_goal_spacing); | ||
| } | ||
| if (!route_point_at_distance( | ||
| env, | ||
| route, | ||
| route_length, | ||
| cursor_idx, | ||
| s_on_lane, | ||
| spacing_meters, | ||
| out_x, | ||
| out_y, | ||
| out_z, | ||
| out_lane_idx, | ||
| out_cursor_idx, | ||
| out_s_on_lane, | ||
| out_heading)) { | ||
| return false; | ||
| } | ||
| if (!constrain_heading) { | ||
| return true; | ||
| } | ||
| if (fabsf(normalize_heading(*out_heading - prev_heading)) <= max_heading_delta_rad) { | ||
| return true; | ||
| } | ||
| } | ||
| return true; | ||
| } |
There was a problem hiding this comment.
do you know if without this we actually have a lot of goals that are not respecting the constraint ?
I have deliberatly skipped this constraint because I assumed the goal sampling for GIGAFLOW paper was only done by doing a random sampling of a lane point within an euclidian distance. But if we follow the lane topology, I expect that we have goals with no shard heading most of time
There was a problem hiding this comment.
I just tried to match it to the gigaflow implementation. I don't think this made any major difference
There was a problem hiding this comment.
I'm afraid this implementation can favorise closer goals -> the closer the goal is, the more likely it is to respect the 60 degrees contrainst
It would be preferable to move this change to a dedicated PR so we can better emphasize the impact of it
| static bool log_pose_overlaps_created_agent( | ||
| Drive *env, | ||
| Agent *agent, | ||
| const int *created_agent_indices, | ||
| int created_agent_count) { | ||
| for (int i = 0; i < created_agent_count; i++) { | ||
| Agent *other = &env->agents[created_agent_indices[i]]; | ||
| float dx = other->sim_x - agent->sim_x; | ||
| float dy = other->sim_y - agent->sim_y; | ||
| float max_overlap_dist = agent->radius + other->radius; | ||
| if (dx * dx + dy * dy > max_overlap_dist * max_overlap_dist) { | ||
| continue; | ||
| } | ||
| if (fabsf(other->sim_z - agent->sim_z) > Z_BUFFER) { | ||
| continue; | ||
| } | ||
| if (check_obb_collision(agent, other)) { | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| static bool spawn_near_drivable_lane(Drive *env, Agent *agent) { | ||
| GridMapEntity entity_list[ROAD_QUERY_ENTITY_COUNT]; | ||
| int list_size = get_neighbors_entities( | ||
| env, | ||
| agent->sim_x, | ||
| agent->sim_y, | ||
| entity_list, | ||
| ROAD_QUERY_ENTITY_COUNT, | ||
| ROAD_OFFSETS, | ||
| 25); | ||
| for (int i = 0; i < list_size; i++) { | ||
| int entity_idx = entity_list[i].entity_idx; | ||
| int geometry_idx = entity_list[i].geometry_idx; | ||
| RoadMapElement *element = &env->road_elements[entity_idx]; | ||
| if (!is_drivable_road_lane(element->type)) { | ||
| continue; | ||
| } | ||
| if (fabsf(element->z[geometry_idx] - agent->sim_z) > Z_BUFFER) { | ||
| continue; | ||
| } | ||
| float lane_distance = compute_point_to_segment_distance( | ||
| agent->sim_x, | ||
| agent->sim_y, | ||
| element->x[geometry_idx], | ||
| element->y[geometry_idx], | ||
| element->x[geometry_idx + 1], | ||
| element->y[geometry_idx + 1]); | ||
| if (lane_distance <= REPLAY_SPAWN_MAX_LANE_DISTANCE_M) { | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| static bool replay_spawn_fit_for_control( | ||
| Drive *env, | ||
| Agent *agent, | ||
| const int *created_agent_indices, | ||
| int created_agent_count) { | ||
| if (agent->sim_length > REPLAY_MAX_CONTROLLED_LENGTH_M) { | ||
| return false; | ||
| } | ||
| if (!spawn_near_drivable_lane(env, agent)) { | ||
| return false; | ||
| } | ||
| if (check_spawn_offroad(env, agent, REPLAY_SPAWN_EDGE_CLEARANCE_M)) { | ||
| return false; | ||
| } | ||
| Agent inflated = *agent; | ||
| inflated.sim_length += 2.0f * REPLAY_SPAWN_LONGITUDINAL_CLEARANCE_M; | ||
| update_agent_radius(&inflated); | ||
| for (int i = 0; i < created_agent_count; i++) { | ||
| Agent *other = &env->agents[created_agent_indices[i]]; | ||
| if (other == agent) { | ||
| continue; | ||
| } | ||
| float dx = other->sim_x - inflated.sim_x; | ||
| float dy = other->sim_y - inflated.sim_y; | ||
| float max_overlap_dist = inflated.radius + other->radius; | ||
| if (dx * dx + dy * dy > max_overlap_dist * max_overlap_dist) { | ||
| continue; | ||
| } | ||
| if (fabsf(other->sim_z - inflated.sim_z) > Z_BUFFER) { | ||
| continue; | ||
| } | ||
| if (check_obb_collision(&inflated, other)) { | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } |
There was a problem hiding this comment.
Ideally this code should be in 123Drive.
But for direct solution as it is, it would better to do inside the init function, similar to remove_bad_trajectories. Either enhance this function or append a new function after
There was a problem hiding this comment.
I think spawn point selection, is somewhat user specific not map specific?
Think this is called twice throughout the code so in the init doesn't make so much sense.
| # Also keep this random fraction of below-threshold transitions; 0 disables the leak | ||
| adv_filter_leak_fraction: 0.0 |
There was a problem hiding this comment.
is this used in training ?
There was a problem hiding this comment.
Currently no. I tried 5% leak but no conclusive improvement. Left it there because I think it is a sensible idea that I might want to revisit later.
| anneal_lr: true | ||
| precision: bfloat16 | ||
| # false: pure float32 matmuls/convs (no TensorFloat-32); requires precision float32 | ||
| tf32: true |
There was a problem hiding this comment.
i think we want a better naming for this one
| float center_x = agent->sim_x; | ||
| float center_y = agent->sim_y; | ||
| float prev_center_x = agent->prev_x; | ||
| float prev_center_y = agent->prev_y; |
There was a problem hiding this comment.
use directly the variable, no need for aliases
Changes I made while the others were on vacation.
https://wandb.ai/emerge_/nightly-multi-long/runs/k_scaled_0028_1000
1T run. Model gets around 200k km/infraction, which is a new best.