77
88# from ..stanley import normalise_angle
99from ...knowledge .vehicle import dynamics
10+ from ...knowledge .vehicle import geometry
1011from ...utils import settings
1112
1213# from ..mathutils import transforms,collisions
@@ -132,27 +133,60 @@ def apply_trail_braking(ds, v_lat, kappa, ax_max, ax_min, ay_max, max_iter=2, to
132133
133134 backward_vs [i - 1 ] = v_allowed
134135
135- # for i in range(N - 2, -1, -1):
136- # ax_limit = limit_ax_for_friction_ellipse(v_profile[i+1], kappa[i+1], abs(ax_min), ay_max)
137- # arg = v_profile[i+1]**2 + 2 * ax_limit * ds[i]
138- # # print("v_profile{i+1}: " + str(v_profile[i+1]))
139- # # print("ax_limit: " + str(ax_limit))
140- # # print("arg: " + str(arg))
141- # v_allowed = np.sqrt(max(arg,0.0))
142- # v_profile[i] = min(v_profile[i], v_allowed)
143-
144- # # v_profile[i] = alpha * v_profile[i] + (1 - alpha) * v_allowed
145-
146- # backward_vs[i] = v_allowed
147-
148-
149136 # --- Check convergence ---
150137 if np .allclose (v_profile , v_old , atol = tol ):
151138 print ("converged in " + str (iteration ) + " iterations" )
152139 break
153140
154141 return v_profile , forward_vs , backward_vs , v_lat
155142
143+ def limit_velocity_by_steering_rate (ds , velocity , wheelbase , max_steering_rate , kappa ):
144+ """
145+ Limits the velocity based on steering angle rate of change.
146+
147+ Parameters:
148+ x (np.ndarray): x positions along the trajectory.
149+ y (np.ndarray): y positions along the trajectory.
150+ velocity (np.ndarray): velocity profile along the trajectory.
151+ wheelbase (float): vehicle's wheelbase (L).
152+ max_steering_rate (float): maximum allowable steering angle rate (rad/s).
153+
154+ Returns:
155+ np.ndarray: limited velocity profile.
156+ """
157+ # # Compute dx, dy
158+ # dx = np.gradient(x)
159+ # dy = np.gradient(y)
160+
161+ # # Compute yaw angle
162+ # yaw = np.arctan2(dy, dx)
163+
164+ # # Compute curvature: kappa = d(yaw) / ds
165+ # ds = np.sqrt(dx**2 + dy**2)
166+ # dyaw = np.gradient(yaw)
167+ # curvature = dyaw / ds
168+
169+ # Compute steering angle delta: delta = arctan(L * kappa)
170+ steering_angle = np .arctan (wheelbase * kappa )
171+
172+ # Compute steering rate: d(delta)/dt
173+ ddelta = np .gradient (steering_angle )
174+ dt = ds / (velocity + 1e-6 ) # Add small value to prevent division by zero
175+ ddelta_dt = ddelta / (dt + 1e-6 )
176+
177+ # Limit velocity where steering rate exceeds max
178+ limited_velocity = np .copy (velocity )
179+ for i in range (len (velocity )):
180+ if abs (ddelta_dt [i ]) > max_steering_rate :
181+ # v = ds / dt = ddelta / d(delta/dt)
182+ limited_velocity [i ] = min (
183+ velocity [i ],
184+ abs (ddelta [i ] / max_steering_rate ) / (ds [i ] + 1e-6 )
185+ )
186+
187+ return limited_velocity
188+
189+
156190def compute_time_profile (xs , ys , v_profile ):
157191 xs = np .array (xs )
158192 ys = np .array (ys )
@@ -203,12 +237,14 @@ def plot_x_y(axis, x, y, x_label, y_label):
203237 axis .set_ylabel (y_label )
204238 axis .grid (True )
205239
206- def compute_velocity_profile (points ):
240+ def compute_velocity_profile (points , plot = None ):
207241
208242 v_max = settings .get ('vehicle.limits.max_speed' )
209243 ax_max = settings .get ('vehicle.limits.max_longitudinal_acceleration' )
210244 ax_min = settings .get ('vehicle.limits.min_longitudinal_acceleration' )
211245 ay_max = settings .get ('vehicle.limits.max_lateral_acceleration' )
246+ max_steering_rate = settings .get ('vehicle.limits.max_steering_rate' )
247+ wheelbase = settings .get ('vehicle.geometry.wheelbase' )
212248
213249 points = np .array (points )
214250 # print(points)
@@ -229,7 +265,14 @@ def compute_velocity_profile(points):
229265
230266 t = compute_time_profile (xs , ys , v_profile )
231267
232- return t , v_profile
268+ v_profile2 = limit_velocity_by_steering_rate (ds , v_profile , wheelbase , max_steering_rate , kappa )
269+
270+ t2 = compute_time_profile (xs , ys , v_profile )
271+
272+ if plot is None :
273+ return t , v_profile
274+ else :
275+ return t , v_profile , t2 , v_profile2
233276
234277
235278
@@ -249,7 +292,7 @@ def compute_velocity_profile(points):
249292
250293 points = list (zip (xs ,ys ))
251294
252- t , v_profile = compute_velocity_profile (points )
295+ t , v_profile , t2 , v_profile2 = compute_velocity_profile (points , plot = True )
253296
254297 # # max long accel: 2.0769700074721493
255298 # # min long accel: -2.6197231578072313
@@ -263,15 +306,18 @@ def compute_velocity_profile(points):
263306 a = dv / dt
264307
265308 plot_x_y (axs [0 , 0 ], t , v_profile , "t" , "v" )
266- plot_x_y (axs [0 , 1 ], t [:- 1 ], a , "t" , "a" )
309+ plot_x_y (axs [0 , 1 ], t2 , v_profile2 , "t" , "v2" )
310+ # plot_x_y(axs[0, 1], t[:-1], a, "t", "a")
267311 # plot_x_y(axs[1, 0], xs, ys, "x", "y")
268312 # plot_x_y(axs[1, 1], t, forward_vs, "t", "forward & backward vs")
269313 # plot_x_y(axs[1, 1], t, backward_vs, "t", "forward & backward vs")
270- plot_x_y (axs [1 , 1 ], t , xs , "t" , "x & y" )
271- plot_x_y (axs [1 , 1 ], t , ys , "t" , "x & y" )
314+ # plot_x_y(axs[1, 1], t, xs, "t", "x & y")
315+ # plot_x_y(axs[1, 1], t, ys, "t", "x & y")
272316 # plt.show()
273317
274318 plot_speed_profile_gradient (fig , axs [1 , 0 ], xs , ys , v_profile )
319+ plot_speed_profile_gradient (fig , axs [1 , 1 ], xs , ys , v_profile2 )
320+
275321
276322 plt .tight_layout ()
277323 plt .show ()
0 commit comments