|
112 | 112 | // => For each entity type in gridmap, diagonal poly-lines -> sqrt(2), include diagonal ends -> 2 |
113 | 113 | #define MAX_ENTITIES_PER_CELL 30 |
114 | 114 |
|
115 | | -// TARGET_TYPE modes (controls what target info is in observations) |
| 115 | +// TARGET_TYPE modes (controls what target info is in observations). |
116 | 116 | #define TARGET_STATIC 0 |
117 | 117 | #define TARGET_DYNAMIC 1 |
118 | 118 |
|
@@ -396,6 +396,7 @@ struct Drive { |
396 | 396 | int num_target_waypoints; |
397 | 397 | int logs_capacity; |
398 | 398 | int target_type; |
| 399 | + int goal_on_lane; |
399 | 400 | char *ini_file; |
400 | 401 | int collision_behavior; // 0 = none, 1=stop, 2 = remove |
401 | 402 | int offroad_behavior; // 0 = none, 1=stop, 2 = remove |
@@ -1927,8 +1928,142 @@ static int compute_new_route(Drive *env, int agent_idx, int current_lane_idx) { |
1927 | 1928 | return 1; // Success |
1928 | 1929 | } |
1929 | 1930 |
|
| 1931 | +// Pick a random drivable point on the map whose Euclidean distance from |
| 1932 | +// (ref_x, ref_y) lies in [min_dist, max_dist]. Returns 1 on success. |
| 1933 | +static int pick_random_drivable_position( |
| 1934 | + Drive *env, |
| 1935 | + float ref_x, |
| 1936 | + float ref_y, |
| 1937 | + float min_dist, |
| 1938 | + float max_dist, |
| 1939 | + float *out_x, |
| 1940 | + float *out_y, |
| 1941 | + float *out_z) { |
| 1942 | + GridMap *gm = env->grid_map; |
| 1943 | + float cell = GRID_CELL_SIZE; |
| 1944 | + float half_diag = 0.5f * cell * (float) M_SQRT2; |
| 1945 | + float min_d2 = min_dist * min_dist; |
| 1946 | + float max_d2 = max_dist * max_dist; |
| 1947 | + float cell_filter = max_dist + half_diag; |
| 1948 | + float cell_filter2 = cell_filter * cell_filter; |
| 1949 | + |
| 1950 | + int ref_cx = (int) ((ref_x - gm->top_left_x) / cell); |
| 1951 | + int ref_cy = (int) ((ref_y - gm->bottom_right_y) / cell); |
| 1952 | + int half_extent = (int) ceilf(cell_filter / cell); |
| 1953 | + |
| 1954 | + int x_lo = ref_cx - half_extent; |
| 1955 | + int y_lo = ref_cy - half_extent; |
| 1956 | + int x_hi = ref_cx + half_extent; |
| 1957 | + int y_hi = ref_cy + half_extent; |
| 1958 | + if (x_lo < 0) { |
| 1959 | + x_lo = 0; |
| 1960 | + } |
| 1961 | + if (y_lo < 0) { |
| 1962 | + y_lo = 0; |
| 1963 | + } |
| 1964 | + if (x_hi >= gm->grid_cols) { |
| 1965 | + x_hi = gm->grid_cols - 1; |
| 1966 | + } |
| 1967 | + if (y_hi >= gm->grid_rows) { |
| 1968 | + y_hi = gm->grid_rows - 1; |
| 1969 | + } |
| 1970 | + |
| 1971 | + int n_cand = 0; |
| 1972 | + float pick_x = 0.0f, pick_y = 0.0f, pick_z = 0.0f; |
| 1973 | + for (int gy = y_lo; gy <= y_hi; gy++) { |
| 1974 | + float cy = gm->bottom_right_y + (gy + 0.5f) * cell; |
| 1975 | + for (int gx = x_lo; gx <= x_hi; gx++) { |
| 1976 | + float cx = gm->top_left_x + (gx + 0.5f) * cell; |
| 1977 | + float dcx = cx - ref_x; |
| 1978 | + float dcy = cy - ref_y; |
| 1979 | + if (dcx * dcx + dcy * dcy > cell_filter2) { |
| 1980 | + continue; |
| 1981 | + } |
| 1982 | + int gi = gy * gm->grid_cols + gx; |
| 1983 | + for (int i = 0; i < gm->cell_entities_count[gi]; i++) { |
| 1984 | + GridMapEntity e = gm->cells[gi][i]; |
| 1985 | + RoadMapElement *lane = &env->road_elements[e.entity_idx]; |
| 1986 | + if (!is_drivable_road_lane(lane->type)) { |
| 1987 | + continue; |
| 1988 | + } |
| 1989 | + // The grid stores polyline SEGMENTS (start vertex = geometry_idx). |
| 1990 | + // Sample a uniform point along the segment so candidate positions |
| 1991 | + // are continuous along the road rather than quantized to vertices. |
| 1992 | + int k = e.geometry_idx; |
| 1993 | + if (k + 1 >= lane->segment_length) { |
| 1994 | + continue; |
| 1995 | + } |
| 1996 | + float t = (float) rand() / (float) RAND_MAX; |
| 1997 | + float ex = lane->x[k] + t * (lane->x[k + 1] - lane->x[k]); |
| 1998 | + float ey = lane->y[k] + t * (lane->y[k + 1] - lane->y[k]); |
| 1999 | + float ez = lane->z[k] + t * (lane->z[k + 1] - lane->z[k]); |
| 2000 | + float edx = ex - ref_x; |
| 2001 | + float edy = ey - ref_y; |
| 2002 | + float ed2 = edx * edx + edy * edy; |
| 2003 | + if (ed2 < min_d2 || ed2 > max_d2) { |
| 2004 | + continue; |
| 2005 | + } |
| 2006 | + n_cand++; |
| 2007 | + if (rand() % n_cand == 0) { |
| 2008 | + pick_x = ex; |
| 2009 | + pick_y = ey; |
| 2010 | + pick_z = ez; |
| 2011 | + } |
| 2012 | + } |
| 2013 | + } |
| 2014 | + } |
| 2015 | + |
| 2016 | + if (n_cand == 0) { |
| 2017 | + return 0; |
| 2018 | + } |
| 2019 | + *out_x = pick_x; |
| 2020 | + *out_y = pick_y; |
| 2021 | + *out_z = pick_z; |
| 2022 | + return 1; |
| 2023 | +} |
| 2024 | + |
1930 | 2025 | static void compute_goals(Drive *env, int agent_idx) { |
1931 | 2026 | Agent *agent = &env->agents[agent_idx]; |
| 2027 | + |
| 2028 | + // goal_on_lane=False: place each goal at a random drivable point whose |
| 2029 | + // Euclidean distance from the previous anchor (agent for goal 0, previous |
| 2030 | + // goal for subsequent ones) lies in [min_waypoint_spacing, |
| 2031 | + // max_waypoint_spacing]. |
| 2032 | + if (!env->goal_on_lane) { |
| 2033 | + int num_target_waypoints = env->num_target_waypoints; |
| 2034 | + if (num_target_waypoints <= 0 || num_target_waypoints > MAX_TARGET_WAYPOINTS) { |
| 2035 | + num_target_waypoints = MAX_TARGET_WAYPOINTS; |
| 2036 | + } |
| 2037 | + float ref_x = agent->sim_x; |
| 2038 | + float ref_y = agent->sim_y; |
| 2039 | + for (int i = 0; i < num_target_waypoints; i++) { |
| 2040 | + float gx, gy, gz; |
| 2041 | + if (!pick_random_drivable_position( |
| 2042 | + env, |
| 2043 | + ref_x, |
| 2044 | + ref_y, |
| 2045 | + env->min_waypoint_spacing, |
| 2046 | + env->max_waypoint_spacing, |
| 2047 | + &gx, |
| 2048 | + &gy, |
| 2049 | + &gz)) { |
| 2050 | + printf("[GIGAFLOW WARNING] -> pick_random_drivable_position failed for agent %d\n", agent_idx); |
| 2051 | + agent->removed = 1; |
| 2052 | + return; |
| 2053 | + } |
| 2054 | + agent->goal_positions_x[i] = gx; |
| 2055 | + agent->goal_positions_y[i] = gy; |
| 2056 | + agent->goal_positions_z[i] = gz; |
| 2057 | + ref_x = gx; |
| 2058 | + ref_y = gy; |
| 2059 | + } |
| 2060 | + agent->current_goal_idx = 0; |
| 2061 | + agent->goal_position_x = agent->goal_positions_x[0]; |
| 2062 | + agent->goal_position_y = agent->goal_positions_y[0]; |
| 2063 | + agent->goal_position_z = agent->goal_positions_z[0]; |
| 2064 | + return; |
| 2065 | + } |
| 2066 | + |
1932 | 2067 | struct Path *path = agent->path; |
1933 | 2068 |
|
1934 | 2069 | // Validate path exists |
|
0 commit comments