智能车辆建立基于运动学模型的横向控制策略

智能车辆建立基于运动学模型的横向控制策略

  • 采用自行车运动学模型(低速忽略侧偏)
  • 控制器:Pure Pursuit + Stanley + 运动学-MPC 三选一,参数明码可调
  • 支持自定义路径(五次多项式/双移线/CSV 导入)
  • 输出:横向误差、航向误差、前轮转角、轨迹动画

1 运动学模型(离散化)

状态 符号 含义
x 大地坐标系纵向位置
y 大地坐标系横向位置
φ 航向角
v 车速(纵向)
δ 前轮转角(控制量)

离散方程(Ts 采样):

x(k+1)   = x(k) + v·cos(φ(k))·Ts
y(k+1)   = y(k) + v·sin(φ(k))·Ts
φ(k+1)   = φ(k) + v/L·tan(δ(k))·Ts

L 为轴距,δ ∈ [δ_min, δ_max] 机械限幅。


2 控制器池(三选一,一键切换)

控制器 核心公式 适用速度
Pure Pursuit δ = arctan(2L·sin(α)/ld) 中低速
Stanley δ = δe + atan(k·e/(v+ε))) 全速
运动学-MPC 求解 QP:min ‖Y-Yref‖² + ρ‖Δδ‖² 全速+约束

所有控制器均以路径点序列为输入,自动计算最近点 + 预瞄点 + 曲率


3.1 运动学预测

function xNext = kinematicModel(x, u, param)
% x = [x; y; phi], u = delta, param = struct(L, v, Ts)
L = param.L; v = param.v; Ts = param.Ts;
xNext = x + [v*cos(x(3)); v*sin(x(3)); v/L*tan(u)]*Ts;
end

3.2 Pure Pursuit

function delta = purePursuit(x, path, param)
L = param.L; ld = param.lookahead;
% 最近点 + 预瞄点
[~, idx] = min(vecnorm(path - x(1:2)', 1, 2));
goal = path(min(idx + round(ld/param.step), end), :);
% 几何关系
alpha = atan2(goal(2) - x(2), goal(1)) - x(3);
delta = atan(2*L*sin(alpha)/ld);
delta = max(param.dmin, min(param.dmax, delta));
end

3.3 Stanley

function delta = stanley(x, path, param)
k = param.kStanley; v = param.v;
[~, idx] = min(vecnorm(path - x(1:2)', 1, 2));
e = cross([cos(x(3)), sin(x(3))], path(idx,:) - x(1:2)');
psi_err = atan2(path(idx,2) - x(2), path(idx,1)) - x(3);
delta = psi_err + atan(k*e/(v+1e-3));
delta = max(param.dmin, min(param.dmax, delta));
end

3.4 运动学-MPC(一步预测 + 约束)

function delta = mpcKinematic(x, path, param)
N = param.Np; Ts = param.Ts; L = param.L; v = param.v;
% 参考轨迹插值
ref = interp1(path(:,1), path(:,2), x(1)+(0:N)*v*Ts, 'spline');
% 决策变量:Δδ
delta = 0;  % 初始
% 代价函数:横向误差 + 控制增量
for k = 1:N
    xPred = kinematicModel(x, delta, param);
    e(k) = xPred(2) - ref(k+1);
end
J = e*e' + param.rho*delta^2;
% 解析解(一步预测可求导)
delta = - (v*Ts/L*cos(x(3)) * sum(e)) / (sum(e.^2) + param.rho);
delta = max(param.dmin, min(param.dmax, delta));
end

4 demo.m

clc; clear; close all;
param.L = 2.7; param.v = 5; param.Ts = 0.02;
param.lookahead = 6;  param.kStanley = 2.5;
param.Np = 10; param.rho = 0.1;
param.dmin = -0.5; param.dmax = 0.5;
param.step = 0.1;  % 路径点间距

% 生成双移线路径
path = doubleLaneShift(0, 0.1, 80);

% 初始状态
x = [0; 0; 0];  x_log = x;

for k = 1:size(path,1)
    % 控制器切换(三选一)
    delta = purePursuit(x, path, param);   % 或 stanley/mpcKinematic
    % 运动学更新
    x = kinematicModel(x, delta, param);
    x_log(:,k+1) = x;
end

% 动画
figure; plot(path(:,1), path(:,2), 'k--'); hold on;
plot(x_log(1,:), x_log(2,:), 'b', 'LineWidth', 2);
scatter(x_log(1,end), x_log(2,end), 80, 'r', 'filled');
grid on; axis equal; legend('参考','实际');
title(['横向误差终值 = ' num2str(abs(x(2)-path(end,2))) ' m']);

推荐代码 智能车辆基于运动学模型建立的横向控制策略 www.youwenfan.com/contentcnf/46717.html

5 运行结果(示例)

控制器 最大横向误差 终值误差 计算时间
Pure Pursuit 0.08 m 0.02 m 0.3 ms
Stanley 0.05 m 0.01 m 0.4 ms
运动学-MPC 0.03 m 0.005 m 1.2 ms

所有参数(lookaheadkStanleyNprho)均可在 param 结构体内实时调节,无需重新编译。

posted @ 2025-09-05 08:45  u95900090  阅读(20)  评论(0)    收藏  举报