|
10 | 10 | import matplotlib.patches as patches |
11 | 11 | import math |
12 | 12 |
|
| 13 | + |
| 14 | +from scipy.optimize import minimize |
| 15 | + |
13 | 16 | def detect_collision(curr_x: float, curr_y: float, curr_v: float, obj: AgentState, min_deceleration: float, max_deceleration: float) -> Tuple[bool, float]: |
14 | 17 | """Detects if a collision will occur with the given object and return deceleration to avoid it.""" |
15 | 18 |
|
@@ -122,6 +125,87 @@ def detect_collision(curr_x: float, curr_y: float, curr_v: float, obj: AgentStat |
122 | 125 | return False, 0.0 |
123 | 126 |
|
124 | 127 | return True, deceleration |
| 128 | + |
| 129 | +def detect_collision_analytical(r_pedestrain_y: float, p_vehicle_left_y_after_t: float, p_vehicle_right_y_after_t: float) -> bool: |
| 130 | + """Detects if a collision will occur with the given object and return deceleration to avoid it. Analytical""" |
| 131 | + |
| 132 | + if r_pedestrain_y > p_vehicle_left_y_after_t and r_pedestrain_y < p_vehicle_right_y_after_t: |
| 133 | + return True |
| 134 | + |
| 135 | + return False |
| 136 | + |
| 137 | + |
| 138 | +def get_minimum_deceleration_for_collision_avoidance(curr_x: float, curr_y: float, curr_v: float, obj: AgentState, min_deceleration: float, max_deceleration: float) -> Tuple[bool, float]: |
| 139 | + """Detects if a collision will occur with the given object and return deceleration to avoid it. Via Optimization""" |
| 140 | + |
| 141 | + # Get the object's position and velocity |
| 142 | + obj_x = obj.pose.x |
| 143 | + obj_y = obj.pose.y |
| 144 | + obj_v_x = obj.velocity[0] |
| 145 | + obj_v_y = obj.velocity[1] |
| 146 | + |
| 147 | + |
| 148 | + vehicle_length = 3 |
| 149 | + vehicle_width = 2 |
| 150 | + |
| 151 | + vehicle_buffer_x = 3.0 |
| 152 | + vehicle_buffer_y = 1.5 |
| 153 | + |
| 154 | + vehicle_front = curr_x + vehicle_length |
| 155 | + vehicle_back = curr_x |
| 156 | + vehicle_left = curr_y + vehicle_width / 2 |
| 157 | + vehicle_right = curr_y - vehicle_width / 2 |
| 158 | + |
| 159 | + r_vehicle_front = vehicle_front - vehicle_front - vehicle_buffer_x |
| 160 | + r_vehicle_back = vehicle_back - vehicle_front - vehicle_buffer_x |
| 161 | + r_vehicle_left = vehicle_left - vehicle_buffer_y |
| 162 | + r_vehicle_right = vehicle_right + vehicle_buffer_y |
| 163 | + r_vehicle_v_x = curr_v |
| 164 | + r_vehicle_v_y = 0 |
| 165 | + |
| 166 | + r_pedestrain_x = obj_x - vehicle_front |
| 167 | + r_pedestrain_y = obj_y |
| 168 | + r_pedestrain_v_x = obj_v_x |
| 169 | + r_pedestrain_v_y = obj_v_y |
| 170 | + |
| 171 | + |
| 172 | + r_velocity_x_from_vehicle = r_vehicle_v_x - r_pedestrain_v_x |
| 173 | + r_velocity_y_from_vehicle = r_vehicle_v_y - r_pedestrain_v_y |
| 174 | + |
| 175 | + t_to_r_pedestrain_x = (r_pedestrain_x - r_vehicle_front) / r_velocity_x_from_vehicle |
| 176 | + |
| 177 | + p_vehicle_left_y_after_t = r_vehicle_left + r_velocity_y_from_vehicle * t_to_r_pedestrain_x |
| 178 | + p_vehicle_right_y_after_t = r_vehicle_right + r_velocity_y_from_vehicle * t_to_r_pedestrain_x |
| 179 | + |
| 180 | + if not detect_collision_analytical(r_pedestrain_y, p_vehicle_left_y_after_t, p_vehicle_right_y_after_t): |
| 181 | + return 0.0 |
| 182 | + |
| 183 | + yaw = None |
| 184 | + minimum_deceleration = None |
| 185 | + if yaw is None: |
| 186 | + if math.abs(r_velocity_y_from_vehicle) > 0.1: |
| 187 | + if r_velocity_y_from_vehicle > 0.1: |
| 188 | + # Vehicle Left would be used to yield |
| 189 | + r_pedestrain_y_temp = r_pedestrain_y + math.abs(r_vehicle_left) |
| 190 | + elif r_velocity_y_from_vehicle < -0.1: |
| 191 | + # Vehicle Right would be used to yield |
| 192 | + r_pedestrain_y_temp = r_pedestrain_y - math.abs(r_vehicle_right) |
| 193 | + |
| 194 | + softest_accleration = 2 * r_velocity_y_from_vehicle * (r_velocity_y_from_vehicle * r_pedestrain_x - r_velocity_x_from_vehicle * r_pedestrain_y_temp) / r_pedestrain_y_temp**2 |
| 195 | + peak_y = -(r_velocity_x_from_vehicle * r_velocity_y_from_vehicle) / softest_accleration |
| 196 | + if math.abs(peak_y) > math.abs(r_pedestrain_y_temp): |
| 197 | + minimum_deceleration = math.abs(softest_accleration) |
| 198 | + else: |
| 199 | + softest_accleration = - (r_velocity_x_from_vehicle**2) / (2 * r_pedestrain_x) |
| 200 | + minimum_deceleration = math.abs(softest_accleration) |
| 201 | + |
| 202 | + else: |
| 203 | + minimum_deceleration = r_velocity_x_from_vehicle**2 / (2 * r_pedestrain_x) |
| 204 | + else: |
| 205 | + pass |
| 206 | + |
| 207 | + return math.max(math.min(minimum_deceleration, max_deceleration), min_deceleration) |
| 208 | + |
125 | 209 |
|
126 | 210 | def longitudinal_plan(path : Path, acceleration : float, deceleration : float, max_speed : float, current_speed : float, |
127 | 211 | method : str) -> Trajectory: |
@@ -895,23 +979,11 @@ def update(self, state : AllState): |
895 | 979 | #get the object we are yielding to |
896 | 980 | obj = state.agents[r.obj2] |
897 | 981 |
|
898 | | - detected, deceleration = detect_collision(abs_x, abs_y, curr_v, obj, self.min_deceleration, self.max_deceleration) |
899 | | - if isinstance(deceleration, list): |
900 | | - print("@@@@@ INPUT", deceleration) |
901 | | - time_collision = deceleration[1] |
902 | | - distance_collision = deceleration[0] |
903 | | - b = 3*time_collision - 2*curr_v |
904 | | - c = curr_v**2 - 3*distance_collision |
905 | | - desired_speed = (-b + (b**2 - 4*c)**0.5)/2 |
906 | | - deceleration = 1.5 |
907 | | - print("@@@@@ YIELDING", desired_speed) |
908 | | - route_with_lookahead = route.trim(closest_parameter,closest_parameter + distance_collision) |
909 | | - traj = longitudinal_plan(route_with_lookahead, self.acceleration, deceleration, desired_speed, curr_v) |
910 | | - return traj |
911 | | - else: |
912 | | - if detected and deceleration > 0: |
913 | | - yield_deceleration = max(deceleration, yield_deceleration) |
914 | | - should_yield = True |
| 982 | + deceleration = get_minimum_deceleration_for_collision_avoidance(abs_x, abs_y, curr_v, obj, self.min_deceleration, self.max_deceleration) |
| 983 | + print("deceleration: ", deceleration) |
| 984 | + if deceleration > 0: |
| 985 | + yield_deceleration = max(deceleration, yield_deceleration) |
| 986 | + should_yield = True |
915 | 987 |
|
916 | 988 | print("should yield: ", should_yield) |
917 | 989 |
|
|
0 commit comments