1. 项目概述:基于DDPG的车辆纵向跟驰控制
在智能驾驶领域,车辆纵向跟驰控制是个经典问题。简单说就是让后车(自车)能自动跟随前车,保持安全距离的同时尽量平稳行驶。传统方法用PID控制居多,但遇到复杂路况或前车急加减速时,效果往往不尽如人意。这正是我们尝试用深度强化学习(DRL)中的DDPG算法来解决的问题。
DDPG(Deep Deterministic Policy Gradient)属于Actor-Critic架构的强化学习算法,特别适合处理连续动作空间的控制问题。跟驰控制中,油门和刹车的力度都是连续值,用DDPG再合适不过。我在实际项目中验证过,相比传统方法,DDPG能更好地适应前车的各种加减速模式,控制更平滑,乘坐舒适性提升明显。
这个项目的核心输入包括前车的加速度、速度、位置信息,以及自车的初始状态。输出则是自车的控制指令(油门/刹车)。难点在于如何设计合理的奖励函数,让智能体既保持安全距离,又避免频繁加减速。下面我会详细拆解整个实现过程。
2. 环境建模与参数设置
2.1 车辆动力学模型
首先需要建立车辆纵向动力学模型。我采用简化模型,主要考虑以下方程:
位置更新:x(t+1) = x(t) + v(t)*Δt + 0.5*a(t)*Δt² 速度更新:v(t+1) = v(t) + a(t)*Δt 加速度计算:a(t) = (F_engine - F_brake - F_resistance)/m其中阻力F_resistance包括:
- 空气阻力:0.5ρCdAv²
- 滚动阻力:mgCr
- 坡度阻力(平路可忽略)
在MATLAB中,我用Simulink搭建了这个模型。实测时发现,模型精度对学习效果影响很大。如果简化过度(比如忽略空气阻力),实际控制时会出现速度波动。建议至少保留空气阻力和滚动阻力两项。
2.2 状态空间与动作空间定义
**状态空间(State)**包含:
- 自车速度 v_ego
- 前车速度 v_lead
- 两车距离 d_rel
- 前车加速度 a_lead
- 自车加速度 a_ego(可选)
**动作空间(Action)**为:
- 油门开度 [0,1]
- 刹车力度 [0,1]
注意这两个动作需要互斥处理。我的做法是:
if action(1) > 0 throttle = action(1); brake = 0; else throttle = 0; brake = -action(1); end2.3 关键参数设置
| 参数 | 推荐值 | 说明 |
|---|---|---|
| 时间步长Δt | 0.1s | 大于0.2s会导致控制滞后 |
| 最大跟车距离 | 50m | 根据实际需求调整 |
| 最小安全距离 | 5m | 防止碰撞 |
| 速度范围 | [0, 120km/h] | 换算为[0, 33.3m/s] |
提示:最小安全距离建议设为2秒规则,即d_min = max(5m, 2*v_ego)。这样速度越高,安全距离越大。
3. DDPG算法实现细节
3.1 网络结构设计
DDPG需要四个神经网络:Actor(策略网络)、Critic(Q网络),以及它们对应的目标网络。我的配置如下:
Actor网络(MATLAB示例):
actorNetwork = [ featureInputLayer(numObservations) fullyConnectedLayer(128) reluLayer fullyConnectedLayer(64) reluLayer fullyConnectedLayer(2) tanhLayer]; % 输出[-1,1],需映射到实际动作范围Critic网络:
statePath = [ featureInputLayer(numObservations) fullyConnectedLayer(128) reluLayer]; actionPath = [ featureInputLayer(numActions) fullyConnectedLayer(128) reluLayer]; commonPath = [ concatenationLayer(1,2) fullyConnectedLayer(64) reluLayer fullyConnectedLayer(1)]; criticNetwork = layerGraph(statePath); criticNetwork = addLayers(criticNetwork, actionPath); criticNetwork = addLayers(criticNetwork, commonPath); criticNetwork = connectLayers(criticNetwork,'relu_1','concat/in1'); criticNetwork = connectLayers(criticNetwork,'relu_3','concat/in2');3.2 奖励函数设计
奖励函数是指挥棒,直接决定智能体的行为。经过多次调参,我的最终方案:
reward = w1*(v_ego - v_desired)² + w2*exp(-d_rel/d_safe) + w3*a_ego² + w4*jerk²其中:
- 第一项鼓励保持期望速度
- 第二项惩罚跟车过近(指数衰减)
- 第三项惩罚急加速/急刹车
- 第四项惩罚加加速度(jerk),提升舒适性
权重建议初始值:w1=0.1, w2=10, w3=0.01, w4=0.05。实际效果如下表:
| 权重组合 | 跟车效果 | 舒适性 |
|---|---|---|
| w2过大(>20) | 距离保持好,但速度波动大 | 差 |
| w3过小(<0.005) | 刹车突兀 | 差 |
| 推荐值 | 平衡 | 良好 |
3.3 训练技巧
经验回放:缓冲区大小至少1e5。我发现优先经验回放(Prioritized Experience Replay)能提升约30%的收敛速度。
探索策略:采用OU噪声,参数设置:
ouNoise = ouNoiseOptions('Theta',0.15,'Mean',0,'Sigma',0.2);训练后期可逐步减小Sigma。
学习率:
- Actor:1e-4
- Critic:1e-3
太高会导致Q值爆炸,太低则收敛慢。
4. MATLAB实现关键代码
4.1 环境封装
classdef CarFollowingEnv < rl.env.MATLABEnvironment properties % 参数初始化 LeadCarSpeed = 20; % 前车初始速度(m/s) EgoCarSpeed = 18; % 自车初始速度 MaxDistance = 50; % 最大跟车距离 MinDistance = 5; % 最小安全距离 TimeStep = 0.1; % 时间步长(s) end methods function this = CarFollowingEnv() % 初始化观测和动作空间 ObservationInfo = rlNumericSpec([5 1]); ActionInfo = rlNumericSpec([2 1],'LowerLimit',-1,'UpperLimit',1); this = this@rl.env.MATLABEnvironment(ObservationInfo,ActionInfo); end function [nextobs,reward,isdone,logged] = step(this,action) % 环境状态更新逻辑 % ...详细实现省略... end end end4.2 主训练流程
% 创建环境 env = CarFollowingEnv(); % 创建DDPG agent agentOpts = rlDDPGAgentOptions(... 'SampleTime',env.TimeStep,... 'TargetSmoothFactor',1e-3,... 'ExperienceBufferLength',1e5); agent = rlDDPGAgent(actor,critic,agentOpts); % 训练参数 trainOpts = rlTrainingOptions(... 'MaxEpisodes',1000,... 'StopTrainingCriteria','AverageReward',... 'StopTrainingValue',-10); % 开始训练 trainingStats = train(agent,env,trainOpts);5. 实际效果与调优
5.1 典型训练曲线分析
(注:实际项目应替换为真实曲线)
- 前200回合:回报波动大,智能体在随机探索
- 200-600回合:快速上升期,策略明显改善
- 600回合后:趋于稳定,可考虑停止训练
5.2 实车测试常见问题
问题:前车急刹时反应迟钝
解决:在奖励函数中增加距离项的权重,同时减小加速度惩罚项问题:速度控制存在稳态误差
解决:在Actor网络输出层增加积分项(类似PID中的I项)问题:不同初始条件下表现不稳定
解决:在训练时随机化初始条件(速度、距离),增强泛化能力
5.3 性能优化技巧
- 并行训练:用
parfor并行跑多个环境实例,提速3-5倍 - 早期终止:当连续50回合平均回报无提升时自动停止
- 混合精度:MATLAB R2022a后支持,可减少显存占用
6. 扩展应用与改进方向
6.1 多车协同控制
将单前车扩展为多前车观测:
ObservationInfo = rlNumericSpec([5*N 1]); % N为前车数量需要修改奖励函数,考虑多车影响。
6.2 结合预测模型
加入LSTM预测前车轨迹:
actorNetwork = [ sequenceInputLayer(numObservations) lstmLayer(64) fullyConnectedLayer(2) tanhLayer];6.3 硬件部署
通过MATLAB Coder生成C++代码,部署到嵌入式设备。实测在Jetson Xavier上能跑到100Hz的控制频率。
这个项目最让我意外的是DDPG对复杂场景的适应能力。有次测试时前车突然从80km/h急刹到20km/h,传统PID控制器出现了明显超调,而DDPG agent却能平滑过渡,保持恰到好处的安全距离。这让我确信强化学习在控制领域大有可为。