Skip to content

Commit e552dcb

Browse files
committed
feat: Add vehicle model rendering function and pause simulation function
1 parent c905175 commit e552dcb

File tree

1 file changed

+104
-6
lines changed

1 file changed

+104
-6
lines changed

PathTracking/pure_pursuit/pure_pursuit.py

Lines changed: 104 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
WB = 2.9 # [m] wheel base of vehicle
1919

2020
show_animation = True
21-
21+
pause_simulation = False # 新增暂停标志
2222

2323
class State:
2424

@@ -141,7 +141,94 @@ def plot_arrow(x, y, yaw, length=1.0, width=0.5, fc="r", ec="k"):
141141
plt.arrow(x, y, length * math.cos(yaw), length * math.sin(yaw),
142142
fc=fc, ec=ec, head_width=width, head_length=width)
143143
plt.plot(x, y)
144-
144+
def plot_vehicle(x, y, yaw, steer=0.0, color='blue'):
145+
"""
146+
绘制带四个车轮的车辆模型
147+
Args:
148+
x, y: 车辆中心位置
149+
yaw: 车辆航向角
150+
steer: 转向角
151+
color: 车辆颜色
152+
"""
153+
# 车辆参数
154+
LENGTH = WB + 1.0 # 车长
155+
WIDTH = 2.0 # 车宽
156+
WHEEL_LEN = 0.6 # 车轮长度
157+
WHEEL_WIDTH = 0.2 # 车轮宽度
158+
159+
def plot_wheel(x, y, yaw, steer=0.0):
160+
"""绘制单个车轮"""
161+
wheel = np.array([
162+
[-WHEEL_LEN/2, WHEEL_WIDTH/2],
163+
[WHEEL_LEN/2, WHEEL_WIDTH/2],
164+
[WHEEL_LEN/2, -WHEEL_WIDTH/2],
165+
[-WHEEL_LEN/2, -WHEEL_WIDTH/2],
166+
[-WHEEL_LEN/2, WHEEL_WIDTH/2]
167+
])
168+
169+
# 如果有转向角,先旋转车轮
170+
if steer != 0:
171+
c, s = np.cos(steer), np.sin(steer)
172+
rot_steer = np.array([[c, -s], [s, c]])
173+
wheel = wheel @ rot_steer.T
174+
175+
# 考虑车辆朝向
176+
c, s = np.cos(yaw), np.sin(yaw)
177+
rot_yaw = np.array([[c, -s], [s, c]])
178+
wheel = wheel @ rot_yaw.T
179+
180+
# 平移到指定位置
181+
wheel[:, 0] += x
182+
wheel[:, 1] += y
183+
184+
plt.plot(wheel[:, 0], wheel[:, 1], color=color)
185+
186+
# 计算车身四个角点
187+
corners = np.array([
188+
[-LENGTH/2, WIDTH/2],
189+
[LENGTH/2, WIDTH/2],
190+
[LENGTH/2, -WIDTH/2],
191+
[-LENGTH/2, -WIDTH/2],
192+
[-LENGTH/2, WIDTH/2]
193+
])
194+
195+
# 旋转矩阵
196+
c, s = np.cos(yaw), np.sin(yaw)
197+
Rot = np.array([[c, -s], [s, c]])
198+
199+
# 旋转并平移车身
200+
rotated = corners @ Rot.T
201+
rotated[:, 0] += x
202+
rotated[:, 1] += y
203+
204+
# 绘制车身
205+
plt.plot(rotated[:, 0], rotated[:, 1], color=color)
206+
207+
# 绘制四个车轮
208+
# 前轮(左)
209+
plot_wheel(x + LENGTH/4 * c - WIDTH/2 * s,
210+
y + LENGTH/4 * s + WIDTH/2 * c,
211+
yaw, steer)
212+
# 前轮(右)
213+
plot_wheel(x + LENGTH/4 * c + WIDTH/2 * s,
214+
y + LENGTH/4 * s - WIDTH/2 * c,
215+
yaw, steer)
216+
# 后轮(左)
217+
plot_wheel(x - LENGTH/4 * c - WIDTH/2 * s,
218+
y - LENGTH/4 * s + WIDTH/2 * c,
219+
yaw)
220+
# 后轮(右)
221+
plot_wheel(x - LENGTH/4 * c + WIDTH/2 * s,
222+
y - LENGTH/4 * s - WIDTH/2 * c,
223+
yaw)
224+
225+
# 添加键盘事件处理函数
226+
def on_key(event):
227+
global pause_simulation
228+
if event.key == ' ': # 空格键
229+
pause_simulation = not pause_simulation
230+
elif event.key == 'escape':
231+
exit(0)
145232

146233
def main():
147234
# target course
@@ -177,18 +264,29 @@ def main():
177264
if show_animation: # pragma: no cover
178265
plt.cla()
179266
# for stopping simulation with the esc key.
180-
plt.gcf().canvas.mpl_connect(
181-
'key_release_event',
182-
lambda event: [exit(0) if event.key == 'escape' else None])
183-
plot_arrow(state.x, state.y, state.yaw)
267+
plt.gcf().canvas.mpl_connect('key_release_event', on_key)
268+
plot_vehicle(state.x, state.y, state.yaw, di) # di 是转向角
184269
plt.plot(cx, cy, "-r", label="course")
185270
plt.plot(states.x, states.y, "-b", label="trajectory")
186271
plt.plot(cx[target_ind], cy[target_ind], "xg", label="target")
187272
plt.axis("equal")
188273
plt.grid(True)
189274
plt.title("Speed[km/h]:" + str(state.v * 3.6)[:4])
275+
plt.legend() # 添加这一行显示图例
276+
277+
# 添加暂停状态显示
278+
if pause_simulation:
279+
plt.text(0.02, 0.95, 'PAUSED', transform=plt.gca().transAxes,
280+
bbox=dict(facecolor='red', alpha=0.5))
281+
190282
plt.pause(0.001)
191283

284+
# 暂停处理
285+
while pause_simulation:
286+
plt.pause(0.1) # 降低 CPU 占用
287+
if not plt.get_fignums(): # 检查窗口是否被关闭
288+
exit(0)
289+
192290
# Test
193291
assert lastIndex >= target_ind, "Cannot goal"
194292

0 commit comments

Comments
 (0)