车辆纵向分层跟踪控制

carsim 与 simulink联合仿真实现车辆速度跟踪控制

上层:双PID 控制器
下层:逆驱动模型、逆制动模型,驱动制动切换模型

上层包括位置 pid 与速度 pid 两个控制器,求的是加速度的补偿值,并将其转化为驱动力矩与制动主缸压力,并且驱动力矩与发动机转速转化为节气门开度,最后 carsim 的输入为节气门开度与制动主缸压力。

同时上层包含驱动力矩与发动机转速转化为节气门开度的小程序,如图所示,,发动机map 图

下层控制器,保证合理地驱动和制动,即切换模块,如图所示。

可自定义期望纵向速度曲线
版本 carsim2019.0➕simulink2022a
先运行文件 1,生成 map三位维图
在这里插入图片描述

MATLAB 代码,包含发动机 Map 图的生成(文件 1)以及 Simulink 中用于Map 数据的脚本。

clear; clc; close all;

% — 1. 定义发动机转速和节气门开度范围 —
% 转速范围:500 rpm 到 6000 rpm
engine_speed = 500💯6000;
% 节气门开度:0 到 100%
throttle_pos = 0:5:100;

% — 2. 构建发动机扭矩 Map (仿真数据/拟合数据) —
% 在实际工程中,这里通常读取 Excel 或 CSV 测试数据
% 这里使用经验公式模拟发动机特性曲面
[Speed, Throttle] = meshgrid(engine_speed, throttle_pos);

% 模拟扭矩曲面公式 (仅作演示,实际请替换为真实台架数据)
% 扭矩随转速先升后降,随节气门线性增加
Torque = (Throttle/100) .* (-1e-5 .* (Speed-3500).^2 + 250);

% 修正物理边界:转速过低时扭矩为0
Torque(Speed dead_zone * m
% — 驱动模式 —
brake_pressure_out = 0; % 制动释放

% 逆驱动模型:力 -> 扭矩
T_engine_req = (F_cmd * r_wheel) / (i_gear * eta);

% 逆查表:扭矩 + 转速 -> 节气门
% 注意:此处需调用 Simulink 的 n-D Lookup Table 模块,
% 或者在此处加载预先计算好的 Map 数据
rpm = v_current / (pir_wheel) * 60 * i_gear; % 估算转速

% 伪代码逻辑:throttle = LookupTable(T_engine_req, rpm)
% 这里用简单的线性近似代替查表
if rpm > 1000
    throttle_out = min(100, T_engine_req * 0.5); 
else
    throttle_out = 0;
end

elseif F_cmd 压力
% F_brake = k * P_master
k_brake = 20000; % 制动增益系数 (N/bar)
brake_pressure_out = abs(F_cmd) / k_brake;

else
% — 保持/死区 —
throttle_out = 0;
brake_pressure_out = 0;
end

end

使用说明

在 Simulink 中添加 2-D Lookup Table 模块,加载生成的 Map 数据,用于实现“逆发动机模型”。
搭建上述逻辑,Carsim 的 S-Function 模块输入端口连接 throttle_out 和 brake_pressure_out。
Carsim 设置:确保 Carsim 的 External Input 设置为接收 Throttle 和 Brake Pressure 信号。
在这里插入图片描述
车辆纵向动力学仿真 结果,通常用于验证车辆速度跟踪控制算法(如PID、MPC等)的性能。

左侧图表为速度对比,右侧图表为加速度对比。

MATLAB 绘图复现代码

这段代码模拟了图片中的梯形速度工况和相应的加速度响应,并使用了与图片一致的黑色背景和网格风格。

%% 车辆纵向控制仿真结果复现
% 对应图片:速度对比与加速度对比

clear; clc; close all;

% — 1. 构造模拟数据 (梯形速度循环) —
dt = 0.01; % 采样时间
t = 0:dt:39.99; % 时间轴 (约40秒)

% 期望速度 (蓝色线): 梯形波
% 0-5s: 加速, 5-10s: 匀速, 10-15s: 减速, 15-20s: 匀速
V_des = zeros(size(t));
for i = 1:length(t)
if t(i) <= 5
V_des(i) = 2 * t(i); % 0-10 m/s 加速
elseif t(i) <= 10
V_des(i) = 10; % 匀速
elseif t(i) <= 15
V_des(i) = 10 - 2 * (t(i)-10);% 减速到 0
elseif t(i) <= 20
V_des(i) = 0; % 静止
elseif t(i) <= 25
V_des(i) = 2 * (t(i)-20); % 再次加速
elseif t(i) <= 30
V_des(i) = 10; % 匀速
elseif t(i) <= 35
V_des(i) = 10 - 2 * (t(i)-30);% 减速
else
V_des(i) = 0;
end
end

% 实际速度 (绿色线): 模拟一阶滞后响应 (PT1)
% 模拟车辆动力系统的惯性
tau = 0.3; % 时间常数
V_act = 0;
V_history = [];
for i = 1:length(t)
dV = (V_des(i) - V_act) / tau * dt;
V_act = V_act + dV;
V_history = [V_history, V_act];
end

% 加速度 (右侧图): 对速度求导
Acc_des = gradient(V_des, dt);
Acc_act = gradient(V_history, dt);

% 添加一些模拟噪声以匹配图片中的波动
noise = 0.1 * randn(size(t));
Acc_act = Acc_act + noise;

% — 2. 绘图设置 (复刻图片风格) —
set(0, ‘DefaultFigureColor’, [0.15, 0.15, 0.15]); % 设置背景深灰
set(0, ‘DefaultAxesColor’, [0.15, 0.15, 0.15]);
set(0, ‘DefaultAxesXColor’, ‘w’);
set(0, ‘DefaultAxesYColor’, ‘w’);

figure(‘Name’, ‘速度与加速度对比复现’, ‘Position’, [100, 100, 1000, 450]);

% — 左侧图:速度对比 —
subplot(1, 2, 1);
plot(t, V_des, ‘Color’, [0, 0.5, 1], ‘LineWidth’, 1.5); hold on; % 蓝色
plot(t, V_history, ‘Color’, [0, 1, 0], ‘LineWidth’, 1); % 绿色
grid on;
title(‘速度对比’, ‘Color’, ‘w’, ‘FontSize’, 12, ‘FontWeight’, ‘bold’);
xlabel(‘时间 (s)’, ‘Color’, ‘w’);
ylabel(‘速度 (m/s)’, ‘Color’, ‘w’);
legend(‘期望速度输入’, ‘实际速度’, ‘Location’, ‘NorthEast’);
ylim([-1, 12]);
xlim([0, 40]);

% — 右侧图:加速度对比 —
subplot(1, 2, 2);
plot(t, Acc_des, ‘Color’, [0, 0.5, 1], ‘LineWidth’, 1.5); hold on; % 蓝色
plot(t, Acc_act, ‘Color’, [0, 1, 0], ‘LineWidth’, 1); % 绿色
grid on;
title(‘加速度对比’, ‘Color’, ‘w’, ‘FontSize’, 12, ‘FontWeight’, ‘bold’);
xlabel(‘时间 (s)’, ‘Color’, ‘w’);
ylabel(‘加速度 (m/s^2)’, ‘Color’, ‘w’);
legend(‘期望加速度’, ‘实际加速度’, ‘Location’, ‘NorthEast’);
ylim([-3, 3]);
xlim([0, 40]);

% 添加图例中的 Dataset 标记 (模拟图片样式)
text(25, 2.5, ‘Dataset1’, ‘Color’, [0, 0.5, 1], ‘FontSize’, 8);
text(25, 2.0, ‘Dataset2’, ‘Color’, [0, 1, 0], ‘FontSize’, 8);

代码关键点说明

数据构造:代码中构造了一个标准的梯形速度循环(加速-匀速-减速-静止),
动态响应:为了模拟真实的控制效果,代码使用了一阶惯性环节(PT1)来模拟车辆从“期望速度”到“实际速度”的滞后,这解释了为什么绿色曲线会稍微落后于蓝色曲线。
绘图风格:使用了深灰色背景和白色网格,完全复刻了 MATLAB 仿真示波器(Scope)或 Carsim 结果查看器的默认外观。

在这里插入图片描述
(Engine Map)三维曲面图,通常用于车辆纵向控制仿真中。

图中的三个坐标轴分别代表:

X 轴(左下):发动机转速(Engine Speed),范围约 0-8000 rpm。
Y 轴(右下):发动机扭矩(Engine Torque),范围包含负值(制动/倒拖扭矩)和正值(驱动扭矩),约 -100 到 300 Nm。
Z 轴(垂直):节气门开度(Throttle Opening)或油门踏板位置,范围 0-1(即 0%-100%)。

为了复现这个图形,我们需要构建一个模拟的发动机查找表(Look-up Table)数据。由于没有具体的实验数据文件,我将提供一段 MATLAB 代码,通过数学公式拟合出类似的曲面形状(包括怠速区、最大扭矩区、高转速衰减区)。

MATLAB 复现代码

%% 发动机万有特性 Map 图复现
% 复现图片中的三维曲面:节气门开度 vs 转速 & 扭矩

clear; clc; close all;

% — 1. 定义坐标轴范围 —
% 发动机转速 (rpm): 0 到 8000
speed = 0💯8000;
% 发动机扭矩 (Nm): -150 到 300 (包含倒拖扭矩)
torque = -150:5:300;

% 创建网格
[Speed, Torque] = meshgrid(speed, torque);

% — 2. 构建节气门开度模型 (Z轴) —
% 初始化节气门矩阵
Throttle = zeros(size(Speed));

% 模拟发动机物理特性逻辑:
% 1. 怠速以下 (Speed 0): 节气门随扭矩和转速增加而增加
% 3. 负扭矩区 (Torque 1, th = 1; end
end
Throttle(j,i) = th;
end
end

% — 3. 绘图 —
figure(‘Color’, ‘w’); % 白色背景

% 使用 mesh 绘制网格图,模拟图片风格
h = mesh(Speed, Torque, Throttle);

% 设置颜色映射 (类似图片的 Jet 风格)
colormap(jet);
colorbar; % 显示颜色条

% — 4. 细节调整以匹配图片 —
xlabel(‘Engine Speed (rpm)’, ‘FontSize’, 12, ‘FontWeight’, ‘bold’);
ylabel(‘Engine Torque (Nm)’, ‘FontSize’, 12, ‘FontWeight’, ‘bold’);
zlabel(‘Throttle Opening (0-1)’, ‘FontSize’, 12, ‘FontWeight’, ‘bold’);
title(‘Engine Map: Throttle vs Speed & Torque’, ‘FontSize’, 14);

% 设置视角 (调整角度以匹配原图)
view(-45, 30);

% 开启网格
grid on;
box on;

% 优化坐标轴范围
axis([0 8000 -150 300 0 1.1]);

代码逻辑解析

负扭矩区(图片右下侧的垂直面):在代码中,当 Torque 1 时,我们将其限制为 1。这对应了图片顶部平整的区域,代表油门踩到底(WOT, Wide Open Throttle)时的最大能力边界。
曲面弯曲:通过引入 efficiency_factor,模拟了发动机在不同转速下的充气效率变化,使得曲面呈现出图片中那种中间隆起、两边变化的形态。

在这里插入图片描述

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐