车辆横向控制(Lateral Vehicle Control)是自动驾驶和高级驾驶辅助系统(ADAS)中的关键技术之一,其目标是使车辆沿期望路径行驶。在实现这一目标时,常采用前轮反馈控制(Front-wheel Feedback Control)和后轮反馈控制(Rear-wheel Feedback Control)两种策略。下面将从原理、建模、控制律设计、优缺点等方面对二者进行详细说明。

一、基本概念

  • 前轮反馈控制:以车辆前轮(转向轮)为控制输入,通过调节前轮转角来跟踪期望路径。
  • 后轮反馈控制:以车辆后轮为参考点,通过调节前轮转角使后轮轨迹跟踪期望路径。
注:虽然实际控制量仍是前轮转角(因为绝大多数乘用车只能前轮转向),但“后轮反馈”指的是控制器的误差计算基于后轮位置而非前轮或质心。

二、车辆运动学模型(简化自行车模型)

为便于分析,通常采用单车模型(Bicycle Model):

  • 车辆简化为前后两个轮子,前轮可转向,后轮固定。

  • 状态变量包括:
    x,yx,y :车辆参考点坐标(通常取后轴中心)

    ψψ :车辆航向角(Yaw angle)

    vv :纵向速度(假设已知或恒定)

  • 控制输入:前轮转角 δδ

运动学方程(以后轴中心为参考点):
{x˙=vcos⁡(ψ)y˙=vsin⁡(ψ)ψ˙=vLtan⁡(δ)
⎩
⎨
⎧​x˙=vcos(ψ)y˙​=vsin(ψ)ψ˙​=Lv​tan(δ)​

其中 L 为轴距。

三、前轮反馈控制(Front-wheel Feedback Control)

1. 误差定义

将前轮位置作为跟踪点。
前轮坐标:

xf=x+Lcos⁡(ψ)yf=y+Lsin⁡(ψ)
xf​yf​​=x+Lcos(ψ)=y+Lsin(ψ)​

定义横向误差 efef​ 为前轮到期望路径的垂直距离。

同时考虑航向误差 ψe=ψ−ψrefψe​=ψ−ψref​ 。

2. 控制律设计(典型方法:几何法或线性化反馈)

一种常用形式(基于小角度近似):
δ=arctan⁡(LR+k1ef+k2e˙f)
δ=arctan(RL​+k1​ef​+k2​e˙f​)

其中:

  • RR 是期望路径的曲率半径(由路径规划给出),
  • k1,k2​ 为反馈增益。

或在线性化后使用状态反馈:

δ=Lv(ψ˙ref+k1ef+k2(ψ−ψref))
δ=vL​(ψ˙​ref​+k1​ef​+k2​(ψ−ψref​))

3. 特点

  • 优点:
    • 直观,符合驾驶员直觉(看车头方向)。
    • 对高速场景响应较快。
  • 缺点:
    • 在低速或大曲率路径下,前轮可能“冲出”路径外侧。
    • 对路径曲率变化敏感。

四、后轮反馈控制(Rear-wheel Feedback Control)

1. 误差定义

-  以后轮中心(即单车模型的参考点)为跟踪点
-  横向误差 er​ :后轮到期望路径的垂直距离。

-  航向误差仍为 ψe=ψ−ψrefψe​=ψ−ψref​ 。

2. 控制律设计(经典:Stanley 控制器 或 线性状态反馈)

方法一:线性状态反馈(适用于小曲率路径)

对误差动态线性化后得到:
e˙r=vsin⁡(ψe)≈vψeψ˙e=vLδ−ψ˙ref
e˙r​=vsin(ψe​)≈vψe​ψ˙​e​=Lv​δ−ψ˙​ref​

设计控制律:
δ=Lv(ψ˙ref+k1er+k2ψe)
δ=vL​(ψ˙​ref​+k1​er​+k2​ψe​)

方法二:Stanley 控制器(非线性,广泛用于自动驾驶)

δ=ψe+arctan⁡(kerv+v0)
δ=ψe​+arctan(v+v0​ker​​)

其中 k 为增益, v0v0​ 为防止低速发散的小常数。

3. 特点

  • 优点:
    • 后轮轨迹更贴近路径,适合泊车、窄道等场景。
    • 系统稳定性更好,尤其在低速时。
    • 更容易保证整个车身不偏离路径。
  • 缺点:
    • 响应略滞后(因控制目标在后方)。
    • 高速大曲率时可能转向不足。

五、对比总结

项目前轮反馈控制后轮反馈控制
参考点前轮位置后轮位置
适用场景高速巡航、高速公路低速、狭窄道路、自动泊车
路径跟踪精度前轮贴合好,车身可能偏移后轮贴合好,整体车身居中
稳定性对曲率突变敏感更鲁棒,尤其低速
典型算法几何预瞄、纯追踪(Pure Pursuit)前轮版前轮版 Stanley、后轮纯追踪
实际应用较少单独使用广泛用于自动驾驶(如Stanley)
注:Pure Pursuit(纯追踪)算法本质上是一种前轮反馈方法,因为它根据前视点计算前轮转角,使前轮指向目标点。

六、实际工程选择建议

  • 城市低速自动驾驶(<30 km/h):推荐后轮反馈(如Stanley),确保车身不压线。
  • 高速公路场景(>60 km/h):可结合前轮反馈与模型预测控制(MPC),兼顾响应与舒适性。
  • 高精度路径跟踪(如矿区、港口AGV):常以后轮或质心为参考,使用后轮反馈+MPC。

七、扩展:质心反馈控制

除前后轮外,也可选择车辆质心作为反馈点,此时需引入质心位置动力学,适用于高动态或四轮转向车辆。

八、前后轮反馈控制代码

码基于单车运动学模型(Bicycle Kinematic Model),并包含路径跟踪仿真。共同设定(适用于两种语言):

  • 车辆模型:后轴中心为参考点
  • 控制输入:前轮转角 delta
  • 路径:正弦曲线 y = 2 * sin(x / 10)
  • 初始状态:x=0, y=-1, psi=0
  • 纵向速度恒定:v = 2.0 m/s
  • 仿真时间:30 秒,步长 0.1 秒

python

  • 切换 use_rear_feedback = False 可测试前轮反馈。
  • 前轮反馈此处为简化实现(实际更常用 Pure Pursuit 或 MPC)。
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d

# ---------- 参数设置 ----------
L = 2.9      # 轴距 (m)
v = 2.0      # 纵向速度 (m/s)
dt = 0.1     # 时间步长 (s)
T = 30       # 总时间 (s)
N = int(T / dt)

# 路径定义:y = 2 * sin(x / 10)
x_ref = np.linspace(0, 50, 500)
y_ref = 2.0 * np.sin(x_ref / 10.0)

# 插值函数(用于计算任意 x 处的 y 和 dy/dx)
f_y = interp1d(x_ref, y_ref, kind='cubic', fill_value="extrapolate")
f_dy = lambda x: (2.0 / 10.0) * np.cos(x / 10.0)  # 解析导数

# ---------- 初始状态 ----------
x, y, psi = 0.0, -1.0, 0.0

# 存储轨迹
x_hist = [x]
y_hist = [y]
psi_hist = [psi]
delta_hist = []

# ---------- 控制增益 ----------
k_e = 1.0    # Stanley 增益(后轮反馈)
k_front = 1.0  # 前轮反馈增益(简化版)

use_rear_feedback = True  # 切换:True 用 Stanley(后轮),False 用前轮反馈

# ---------- 仿真循环 ----------
for i in range(N):
    # 当前位置
    current_x, current_y = x, y

    # 找到路径上最近点(简化:按 x 投影)
    if current_x < x_ref[0]:
        idx = 0
    elif current_x > x_ref[-1]:
        idx = -1
    else:
        idx = np.argmin(np.abs(x_ref - current_x))
    
    x_closest = x_ref[idx]
    y_closest = y_ref[idx]
    dy_dx = f_dy(x_closest)
    psi_path = np.arctan2(dy_dx, 1.0)  # 路径切线角

    if use_rear_feedback:
        # ===== 后轮反馈:Stanley 控制器 =====
        # 横向误差:从后轮到路径的垂直距离(简化为 y 方向投影)
        e_lat = -(current_y - y_closest) * np.cos(psi_path) + (current_x - x_closest) * np.sin(psi_path)
        # 航向误差
        e_psi = psi - psi_path
        # Stanley 控制律
        delta = e_psi + np.arctan2(k_e * e_lat, v + 1e-5)
    else:
        # ===== 前轮反馈控制(简化几何法)=====
        # 前轮位置
        x_f = x + L * np.cos(psi)
        y_f = y + L * np.sin(psi)
        # 前轮到路径的横向误差(简化)
        e_lat_f = -(y_f - f_y(x_f))
        e_psi = psi - psi_path
        # 控制律(近似)
        delta = np.arctan2(L * dy_dx, 1.0) + k_front * e_lat_f

    # 限制转向角(±30度)
    delta = np.clip(delta, -np.pi/6, np.pi/6)

    # 更新车辆状态(运动学模型)
    x += v * np.cos(psi) * dt
    y += v * np.sin(psi) * dt
    psi += (v / L) * np.tan(delta) * dt

    # 存储
    x_hist.append(x)
    y_hist.append(y)
    psi_hist.append(psi)
    delta_hist.append(delta)

# ---------- 绘图 ----------
plt.figure(figsize=(10, 6))
plt.plot(x_ref, y_ref, 'k--', label='Reference Path')
plt.plot(x_hist, y_hist, 'b-', linewidth=2, label='Vehicle Trajectory')
plt.xlabel('X (m)')
plt.ylabel('Y (m)')
plt.title('Lateral Control: {} Feedback'.format('Rear-wheel (Stanley)' if use_rear_feedback else 'Front-wheel'))
plt.legend()
plt.grid(True)
plt.axis('equal')
plt.show()

# 转向角随时间变化
t = np.arange(0, T, dt)
plt.figure()
plt.plot(t, np.array(delta_hist) * 180 / np.pi)
plt.xlabel('Time (s)')
plt.ylabel('Steering Angle (deg)')
plt.title('Steering Command')
plt.grid(True)
plt.show()

matlab

  • 若 MATLAB 版本 ≥ R2016b,可直接用 string 或逻辑索引替代 ternary。
  • interp1 使用 ‘pchip’ 保证平滑导数。
%% 车辆横向控制:前轮 vs 后轮反馈
clear; clc; close all;

% ---------- 参数 ----------
L = 2.9;          % 轴距 (m)
v = 2.0;          % 纵向速度 (m/s)
dt = 0.1;         % 时间步长
T = 30;           % 总时间
N = T / dt;

% 路径:y = 2*sin(x/10)
x_ref = linspace(0, 50, 500);
y_ref = 2 * sin(x_ref / 10);

% 插值函数
f_y = @(x) interp1(x_ref, y_ref, x, 'pchip', 'extrap');
f_dy = @(x) (2/10) * cos(x / 10);  % 解析导数

% 初始状态
x = 0; y = -1; psi = 0;

% 存储
x_hist = zeros(1, N+1); y_hist = zeros(1, N+1); psi_hist = zeros(1, N+1);
delta_hist = zeros(1, N);

x_hist(1) = x; y_hist(1) = y; psi_hist(1) = psi;

% 控制参数
k_e = 1.0;        % Stanley 增益
k_front = 1.0;    % 前轮反馈增益

useRearFeedback = true;  % true: Stanley (后轮), false: 前轮反馈

% ---------- 仿真 ----------
for i = 1:N
    % 找最近点(按 x 投影)
    [~, idx] = min(abs(x_ref - x));
    x_c = x_ref(idx);
    y_c = y_ref(idx);
    dy_dx = f_dy(x_c);
    psi_path = atan2(dy_dx, 1);
    
    if useRearFeedback
        % ----- 后轮反馈:Stanley -----
        e_lat = -(y - y_c)*cos(psi_path) + (x - x_c)*sin(psi_path);
        e_psi = psi - psi_path;
        delta = e_psi + atan(k_e * e_lat / (v + 1e-5));
    else
        % ----- 前轮反馈(简化)-----
        x_f = x + L * cos(psi);
        y_f = y + L * sin(psi);
        e_lat_f = -(y_f - f_y(x_f));
        e_psi = psi - psi_path;
        delta = atan(L * dy_dx) + k_front * e_lat_f;
    end
    
    % 限幅 ±30度
    delta = max(min(delta, pi/6), -pi/6);
    
    % 更新状态
    x = x + v * cos(psi) * dt;
    y = y + v * sin(psi) * dt;
    psi = psi + (v / L) * tan(delta) * dt;
    
    % 存储
    x_hist(i+1) = x;
    y_hist(i+1) = y;
    psi_hist(i+1) = psi;
    delta_hist(i) = delta;
end

% ---------- 绘图 ----------
figure;
plot(x_ref, y_ref, 'k--', 'LineWidth', 1.5); hold on;
plot(x_hist, y_hist, 'b-', 'LineWidth', 2);
xlabel('X (m)'); ylabel('Y (m)');
title(sprintf('Lateral Control: %s Feedback', ...
    ternary(useRearFeedback, 'Rear-wheel (Stanley)', 'Front-wheel')));
legend('Reference Path', 'Vehicle Trajectory');
grid on; axis equal;

% 转向角
t = (0:N-1)*dt;
figure;
plot(t, rad2deg(delta_hist), 'r-', 'LineWidth', 1.5);
xlabel('Time (s)'); ylabel('Steering Angle (deg)');
title('Steering Command');
grid on;

% 辅助函数(MATLAB R2016b 以下需定义 ternary)
function out = ternary(condition, a, b)
    if condition, out = a; else, out = b; end
end

代码说明

模块说明
路径表示使用解析函数 + 插值,避免查表误差
误差计算后轮反馈采用垂直距离投影(更准确);前轮反馈简化处理
Stanley 控制器经典后轮反馈方法,含航向误差 + 横向误差耦合
前轮反馈此处为教学简化版,实际工程多用 Pure Pursuit 或 MPC
转向限幅±30°(典型乘用车极限)
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐