"""Path tracking simulation with Stanley steering control and PID speed control.author: Atsushi Sakai (@Atsushi_twi)Ref:- [Stanley: The robot that won the DARPA grand challenge](http://isl.ecst.csuchico.edu/DOCS/darpa2005/DARPA%202005%20Stanley.pdf)- [Autonomous Automobile Path Tracking](https://www.ri.cmu.edu/pub_files/2009/2/Automatic_Steering_Methods_for_Autonomous_Automobile_Path_Tracking.pdf)"""import numpy as npimport matplotlib.pyplot as pltimport sysimport ossys.path.append(os.path.dirname(os.path.abspath(__file__)) +"/../../PathPlanning/CubicSpline/")try:import cubic_spline_plannerexcept:raisek = 0.5 # control gainKp = 1.0 # speed proportional gaindt = 0.1 # [s] time differenceL = 2.9 # [m] Wheel base of vehiclemax_steer = np.radians(30.0) # [rad] max steering angleshow_animation = Trueclass State(object):"""Class representing the state of a vehicle.:param x: (float) x-coordinate:param y: (float) y-coordinate:param yaw: (float) yaw angle:param v: (float) speed"""def __init__(self, x=0.0, y=0.0, yaw=0.0, v=0.0):"""Instantiate the object."""super(State, self).__init__()self.x = xself.y = yself.yaw = yawself.v = vdef update(self, acceleration, delta):"""Update the state of the vehicle.Stanley Control uses bicycle model.:param acceleration: (float) Acceleration:param delta: (float) Steering"""delta = np.clip(delta, -max_steer, max_steer)self.x += self.v * np.cos(self.yaw) * dtself.y += self.v * np.sin(self.yaw) * dtself.yaw += self.v / L * np.tan(delta) * dtself.yaw = normalize_angle(self.yaw)self.v += acceleration * dtdef pid_control(target, current):"""Proportional control for the speed.:param target: (float):param current: (float):return: (float)"""return Kp * (target - current)def stanley_control(state, cx, cy, cyaw, last_target_idx):"""Stanley steering control.:param state: (State object):param cx: ([float]):param cy: ([float]):param cyaw: ([float]):param last_target_idx: (int):return: (float, int)"""current_target_idx, error_front_axle = calc_target_index(state, cx, cy)if last_target_idx >= current_target_idx:current_target_idx = last_target_idx# theta_e corrects the heading errortheta_e = normalize_angle(cyaw[current_target_idx] - state.yaw)# theta_d corrects the cross track errortheta_d = np.arctan2(k * error_front_axle, state.v)# Steering controldelta = theta_e + theta_dreturn delta, current_target_idxdef normalize_angle(angle):"""Normalize an angle to [-pi, pi].:param angle: (float):return: (float) Angle in radian in [-pi, pi]"""while angle > np.pi:angle -= 2.0 * np.piwhile angle < -np.pi:angle += 2.0 * np.pireturn angledef calc_target_index(state, cx, cy):"""Compute index in the trajectory list of the target.:param state: (State object):param cx: [float]:param cy: [float]:return: (int, float)"""# Calc front axle positionfx = state.x + L * np.cos(state.yaw)fy = state.y + L * np.sin(state.yaw)# Search nearest point indexdx = [fx - icx for icx in cx]dy = [fy - icy for icy in cy]d = np.hypot(dx, dy)target_idx = np.argmin(d)# Project RMS error onto front axle vectorfront_axle_vec = [-np.cos(state.yaw + np.pi / 2),-np.sin(state.yaw + np.pi / 2)]error_front_axle = np.dot([dx[target_idx], dy[target_idx]], front_axle_vec)return target_idx, error_front_axledef main():"""Plot an example of Stanley steering control on a cubic spline."""# target courseax = [0.0, 100.0, 100.0, 50.0, 60.0]ay = [0.0, 0.0, -30.0, -20.0, 0.0]cx, cy, cyaw, ck, s = cubic_spline_planner.calc_spline_course(ax, ay, ds=0.1)target_speed = 30.0 / 3.6 # [m/s]max_simulation_time = 100.0# Initial statestate = State(x=-0.0, y=5.0, yaw=np.radians(20.0), v=0.0)last_idx = len(cx) - 1time = 0.0x = [state.x]y = [state.y]yaw = [state.yaw]v = [state.v]t = [0.0]target_idx, _ = calc_target_index(state, cx, cy)while max_simulation_time >= time and last_idx > target_idx:ai = pid_control(target_speed, state.v)di, target_idx = stanley_control(state, cx, cy, cyaw, target_idx)state.update(ai, di)time += dtx.append(state.x)y.append(state.y)yaw.append(state.yaw)v.append(state.v)t.append(time)if show_animation: # pragma: no coverplt.cla()# for stopping simulation with the esc key.plt.gcf().canvas.mpl_connect('key_release_event',lambda event: [exit(0) if event.key == 'escape' else None])plt.plot(cx, cy, ".r", label="course")plt.plot(x, y, "-b", label="trajectory")plt.plot(cx[target_idx], cy[target_idx], "xg", label="target")plt.axis("equal")plt.grid(True)plt.title("Speed[km/h]:" + str(state.v * 3.6)[:4])plt.pause(0.001)# Testassert last_idx >= target_idx, "Cannot reach goal"if show_animation: # pragma: no coverplt.plot(cx, cy, ".r", label="course")plt.plot(x, y, "-b", label="trajectory")plt.legend()plt.xlabel("x[m]")plt.ylabel("y[m]")plt.axis("equal")plt.grid(True)plt.subplots(1)plt.plot(t, [iv * 3.6 for iv in v], "-r")plt.xlabel("Time[s]")plt.ylabel("Speed[km/h]")plt.grid(True)plt.show()if __name__ == '__main__':main()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。