给自动驾驶新手:用Python从零实现运动学自行车模型(附完整代码)
·
给自动驾驶新手:用Python从零实现运动学自行车模型(附完整代码)
自动驾驶技术的核心在于对车辆运动的精确建模。运动学自行车模型(Kinematic Bicycle Model)作为入门级建模方法,通过简化车辆结构为两轮自行车,帮助初学者理解基础原理。本文将带您从零开始,用Python完整实现这一模型,涵盖后轴、前轴及质心三种参考点的代码实现,最终生成可视化轨迹。
1. 环境准备与基础概念
在开始编码前,需要确保Python环境已安装以下库:
pip install numpy matplotlib scipy
运动学自行车模型 的核心假设包括:
- 车辆简化为前后两轮结构(类似自行车)
- 无横向滑移(Nonholonomic约束)
- 转向角变化瞬时完成
模型的关键参数定义:
| 符号 | 含义 | 典型值 |
|---|---|---|
| L | 轴距(前后轮距离) | 2.5m |
| δ | 前轮转向角 | [-0.5,0.5]rad |
| v | 车速 | 5m/s |
注意:实际车辆转向角存在物理限制,仿真时需添加约束条件
2. 后轴参考点模型实现
后轴作为参考点时,车辆状态可表示为:
state = [x, y, theta] # (x坐标,y坐标,航向角)
根据几何关系,推导出微分方程:
dx/dt = v * cos(θ)
dy/dt = v * sin(θ)
dθ/dt = v * tan(δ) / L
Python实现代码:
def kinematic_model_rear(state, t, v, delta, L):
theta = state[2]
dxdt = v * np.cos(theta)
dydt = v * np.sin(theta)
dthetadt = v * np.tan(delta) / L
return [dxdt, dydt, dthetadt]
可视化示例:
# 参数设置
L = 2.5
v = 5.0
delta = np.pi/6 # 30度转向
# 数值积分求解
from scipy.integrate import odeint
t = np.linspace(0, 10, 100)
states = odeint(kinematic_model_rear, [0,0,0], t, args=(v,delta,L))
# 绘制轨迹
plt.plot(states[:,0], states[:,1])
plt.axis('equal')
plt.title('后轴参考点轨迹')
3. 前轴与质心参考点扩展
3.1 前轴参考点模型
前轴作为参考点时,速度方向为δ+θ:
def kinematic_model_front(state, t, v, delta, L):
theta = state[2]
dxdt = v * np.cos(theta + delta)
dydt = v * np.sin(theta + delta)
dthetadt = v * np.tan(delta) / L
return [dxdt, dydt, dthetadt]
3.2 质心参考点模型
引入侧滑角β的概念:
def kinematic_model_cg(state, t, v, delta, L, lr):
theta = state[2]
beta = np.arctan(lr * np.tan(delta) / L)
dxdt = v * np.cos(theta + beta)
dydt = v * np.sin(theta + beta)
dthetadt = v * np.tan(delta) * np.cos(beta) / L
return [dxdt, dydt, dthetadt]
三种模型的轨迹对比:
# 相同参数下仿真
states_rear = odeint(kinematic_model_rear, [0,0,0], t, args=(v,delta,L))
states_front = odeint(kinematic_model_front, [0,0,0], t, args=(v,delta,L))
states_cg = odeint(kinematic_model_cg, [0,0,0], t, args=(v,delta,L,1.5))
plt.plot(states_rear[:,0], states_rear[:,1], label='后轴')
plt.plot(states_front[:,0], states_front[:,1], label='前轴')
plt.plot(states_cg[:,0], states_cg[:,1], label='质心')
plt.legend()
4. 完整仿真系统实现
构建可交互的仿真系统:
class BicycleSimulator:
def __init__(self, L=2.5, lr=1.2):
self.L = L # 轴距
self.lr = lr # 后轴到质心距离
def simulate(self, v, delta, duration=10, ref_point='rear'):
t = np.linspace(0, duration, 100)
if ref_point == 'rear':
states = odeint(kinematic_model_rear, [0,0,0], t, args=(v,delta,self.L))
elif ref_point == 'front':
states = odeint(kinematic_model_front, [0,0,0], t, args=(v,delta,self.L))
else:
states = odeint(kinematic_model_cg, [0,0,0], t, args=(v,delta,self.L,self.lr))
return states
典型应用场景测试:
sim = BicycleSimulator()
# 不同转向角测试
for delta in np.linspace(-0.5, 0.5, 5):
states = sim.simulate(v=3, delta=delta, ref_point='cg')
plt.plot(states[:,0], states[:,1], label=f'delta={delta:.2f}')
plt.legend()
plt.title('不同转向角下的质心轨迹')
5. 进阶应用与问题排查
5.1 转向角速率限制
实际车辆转向存在机械限制,需添加约束:
def constrained_delta(delta_cmd, delta_prev, max_rate=0.1):
delta_change = delta_cmd - delta_prev
if abs(delta_change) > max_rate:
return delta_prev + np.sign(delta_change)*max_rate
return delta_cmd
5.2 常见问题解决方案
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
| 轨迹突然跳变 | 转向角突变 | 添加速率限制 |
| 数值不稳定 | 积分步长过大 | 减小时间步长 |
| 轨迹不符合预期 | 参考点选择错误 | 检查模型公式 |
提示:调试时可先固定转向角,验证直线运动是否正确
6. 模型扩展与性能优化
6.1 动态参数调整
def adaptive_model(state, t, v_func, delta_func, L):
v = v_func(t) # 速度随时间变化
delta = delta_func(t) # 转向角随时间变化
return kinematic_model_rear(state, t, v, delta, L)
6.2 实时可视化技巧
from matplotlib.animation import FuncAnimation
fig, ax = plt.subplots()
line, = ax.plot([], [], 'b-')
def init():
ax.set_xlim(-10, 50)
ax.set_ylim(-10, 10)
return line,
def animate(i):
states = sim.simulate(v=5, delta=0.2, duration=i/10)
line.set_data(states[:,0], states[:,1])
return line,
ani = FuncAnimation(fig, animate, frames=100, init_func=init, blit=True)
实现过程中发现,当转向角超过物理极限时,质心模型的侧滑角计算会出现数值不稳定。解决方法是在arctan计算前添加范围限制:
beta = np.arctan(np.clip(lr * np.tan(delta) / L, -1e5, 1e5))
更多推荐


所有评论(0)