做滑模控制那段时间,我几乎每天都在跟三组参数较劲。切换增益调大了,系统高频抖振明显;调小了,来一个阶跃扰动就出好几度超调。边界层厚度也是同样尴尬,太厚稳态误差变大,太薄又跟没加边界层差不多。后来我把注意力转到自适应调参这个方向,尝试了不少方案,落地效果最好的一组是基于深度确定性策略梯度算法(DDPG)强化学习的滑模控制(SMC)自适应调参优化算法,整套方案在Simulink环境里搭建和验证。这篇文章就是我对整个项目从理论设计、仿真建模到训练调试的一次完整复盘。
如果硬要我总结这套方案的核心价值,一句话:把滑模控制里“靠经验定死”的控制器参数,变成由强化学习智能体根据实时误差和动态响应在线微调。高频抖振被抑制了,突变扰动下也能自动把增益提起来,整个过程不再需要人盯着调参。无论你是刚接触强化学习控制的入门者,还是在SMC上已经踩过很多坑的老手,这套基于Simulink的DDPG-SMC联合仿真流程都可以拿去做参考。
1. 为什么让强化学习介入滑模调参:三个直接痛点决定技术路线
滑模控制的控制器结构本身并不复杂,真正麻烦的是参数。拿最常见的二阶机械系统来说,滑模面通常选为 s = e_dot + c*e,控制律由等效控制项 u_eq 和切换控制项 u_sw 组成。等效控制项把系统状态约束到滑模面上,切换项负责克服不确定性和外部扰动,边界层厚度 delta 则决定符号函数在滑模面附近的连续化近似程度。很多人以为切换增益 k、滑模面系数 c、边界层厚度 delta 各有一个标准值,事实是它们互相制衡:c 决定滑模面附近的动态响应速度,k 决定抗扰动能力,delta 决定抖振抑制程度。三组参数放在一起,没有一个一劳永逸的组合能覆盖全部工况。
如果被控对象工作点相对固定,扰动幅度有限,固定参数的SMC确实能压制住问题。可工程上的难点在于,被控对象不会一直待在实验室的假设里。负载变化、摩擦系数漂移、执行器饱和、噪声水平波动,任何一种情况出现,都意味着当前参数已经不是最优的。固定参数SMC在这种变工况下的表现,要么以高增益硬扛导致控制量长期饱和,要么为了照顾某些极端工况把参数调得很保守,正常工况下跟踪精度又不够。说得直白一点,传统SMC的鲁棒性本质是“用保守参数对抗不确定性”,而不是“跟随不确定性调整自己”。
传统上,自适应滑模控制方向主要靠扰动观测器或者等效扰动估计,把扰动补偿项加到滑模控制律里。这类方法逻辑清晰,但扰动观测器的带宽和模型误差直接影响补偿效果,尤其在扰动突变或模型结构不确定时,补偿项容易出现过冲甚至激发未建模动态。相比这种基于模型的自适应策略,强化学习完全换了一个思路:不显式估计扰动,而是通过试错直接学出一条“参数调节策略”,让控制器参数本身具备在线调整能力。
那为什么选DDPG而不是其他强化学习算法?因为在线调参本质上是一个连续动作空间问题。Q-learning、DQN处理动作空间时需要对动作离散化,参数区间的分辨率完全靠离散粒度和枚举数量堆出来,连续微调很难做到。PPO不是不能做连续控制,但它是on-policy算法,训练样本利用率较低,在仿真环境里每个episode的时长又受控制响应时间约束,整体收敛效率不如DDPG来得直接。DDPG属于确定性策略,配合经验回放机制,可以把探索过程中积累的历史样本反复利用,对控制器参数这类低维但连续的动作输出非常合适。而且DDPG对模型误差的依赖很低,不需要被控对象的精确数学模型,这一点在工程上非常实用。
2. DDPG自适应调参模型的设计关键:观察量、动作量、奖励三者缺一不可
强化学习智能体要在控制回路里做出合理的参数修正决策,首先必须把当前控制状态映射成一个向量。这个向量既要包含控制性能的实时反馈,又要包含动态趋势信息,否则智能体看不到“参数调整之后到底产生了什么效果”。很多第一次做这个方向的人上来就堆观察量,把能测的全塞进去,结果训练收敛速度慢得离谱。观察量设计的目标不是越多越好,而是“最小充分”加“动态趋势”。
我在这个项目里选择的观察量是四组:跟踪误差 e、误差变化率 e_dot、滑模函数 s、上一时刻的控制输入 u。跟踪误差和误差变化率是控制性能最直接的指标,滑模函数 s 则把误差和误差变化率压缩成一个综合量,直接反映系统当前离滑模面的“距离”和“方向”,智能体据此判断该加强切换增益还是放宽边界层。控制输入 u 的反馈非常关键,因为参数调整最终要体现在控制量变化上,没有这个反馈,智能体很难建立“动作-结果”的正确关联。如果你的对象有可测的扰动前馈信息,比如负载力矩传感器,也可以把扰动观测值加进观察量里,但这是加分项而不是必需项。
动作空间设计是另一个容易踩坑的地方。一开始我很自然地想到让智能体直接输出最终的控制器参数,也就是 k、c、delta 三个绝对值。这个方案看似简单,实际训练中问题很大:训练初期策略完全随机,智能体可能直接把 k 从 15 拉到接近 0,或者把 delta 从 0.05 改成 5,控制系统瞬间失稳。状态轨迹一旦发散,后面所有经验都失去了参考价值,梯度更新自然崩溃。
后来我改成增量式参数调节设计,动作向量定义为 a = [Δk, Δc, Δdelta],当前时刻的参数等于上一时刻参数加上动作值,同时给每个参数设置合理的上下限范围。为了让动作输出在训练初期也能保持安全,需要在 Actor 网络的输出层后面接一个数值裁剪环节,把三个增量分别限制在小范围里,比如每一个决策周期内 Δk 限制在 ±0.5 以内,Δc 限制在 ±1.0 以内,Δdelta 限制在 ±0.01 以内。这样不管智能体怎么试错,控制回路都不会因为参数突变而整体发散。这相当于给探索过程加了一个安全边界,属于实际工程里非常必要的处理。
奖励函数是影响收敛质量最关键的一环。我初版只用了跟踪误差的平方作为惩罚,训练结果出现了一种“聪明但偷懒”的策略:智能体为了让误差尽快降到零,把边界层厚度压得很小,导致控制量剧烈抖动,滑模面频繁穿越。出现这个问题的根源在于目标函数里没有对抖振行为做任何约束。后来我把奖励函数调整为分段加权形式:
r = -w1 * e² - w2 * s² - w3 * Δu²
w1、w2、w3 分别对应跟踪精度、滑模趋近质量、控制平滑度的权重,Δu 表示相邻控制步之间控制量和参数变化量的组合量。这个设计把抖振惩罚和控制量平滑惩罚同时塞进去,智能体必须在抗扰能力、收敛速度和稳态平滑之间做权衡,而不是单一指标的最优解。权重设置上,我试下来 w1 取 5、w2 取 1、w3 取 0.1 的效果比较均衡。需要注意的是,这个权重组合比较依赖具体被控对象,换一个系统必须重新试,没有万能参数,建议从误差项主导开始逐步加平滑惩罚。
我把第 2 节里的关键设计参数整理成了一个表,方便对照上手:
| 设计项 | 我的选择 | 设计意图 |
|---|---|---|
| 观察量 | e、e_dot、s、u | 覆盖性能反馈、动态趋势、动作结果闭环 |
| 动作量 | Δk、Δc、Δdelta(增量式) | 避免策略随机期参数突变导致系统发散 |
| 参数上下限 | k∈[2,20],c∈[5,15],delta∈[0.01,0.2] | 约束参数落在合理工程区间 |
| 奖励权重 | w1=5,w2=1,w3=0.1 | 精度优先,兼顾平滑,防止抖振 |
3. Simulink联合仿真架构:把DDPG嵌入SMC控制回路的完整实现
搭建联合仿真的第一步是划分模型边界。整个Simulink模型可以分成五个部分:参考输入、被控对象模型、滑模面计算模块、SMC控制器子系统、DDPG智能体子系统。控制对象我选的是带有参数不确定性的二阶机电模型,模型输出是位移,输入是力,同时注入随机扰动信号模拟负载波动。这个对象虽然简化,但涵盖了SMC最典型的应用场景:非线性摩擦、参数摄动和外部扰动。
滑模面计算模块从跟踪误差和误差变化率计算得到 s,SMC控制器子系统根据 s 计算等效控制项和切换控制项,DDPG智能体子系统接受观察量并输出三个参数修正量。值得注意的是,在这套架构里 SMC 控制器是主回路,DDPG 是参数调节回路,两者是并行关系,DDPG 并不会替代主控制器。强化学习在这个场景里的角色更像是一个“在线调参工程师”,根据控制表现微调控制器参数,而不是直接输出最终控制量。
SMC控制器子系统在Simulink里的实现,我最常用的是 MATLAB Function 模块。控制律写成:
function u = smc_controller(e, edot, c, k, delta) s = edot + c * e; u_eq = nominal_model(e, edot); % 等效控制项 u_sw = -k * tanh(s / delta); % 切换控制项 u = u_eq + u_sw; end这里有两个细节值得注意。一是纯符号函数 sign 在数值仿真里会引起高频振颤,换成 tanh 或者饱和函数 sat 可以把高频切换近似处理掉,tanh 的好处是光滑可导,不会在每一步产生控制量阶跃跳变,这个近似效果实际上就是边界层厚度 delta 的作用。二是 u_eq 必须基于名义模型参数计算,不要引入不确定项,否则会把模型误差带进控制律,影响滑模面的保持性能。
DDPG智能体在Simulink里的接入方式有两种常见选择。第一种是用强化学习工具箱的 RL Agent 模块,第二种是手动把 Actor 网络写成一个 MATLAB Function,训练时再接上训练器。第一次做联合仿真我建议直接用 RL Agent 模块,它能省掉大量接口层面的麻烦。模块输入是观察量向量,输出是动作向量,需要提前在 MATLAB 脚本里定义好观测规范(obsInfo)和动作规范(actInfo),把每个维度的取值范围写清楚。训练配置里,Actor 网络结构我用了两层全连接,每层 128 个神经元,中间激活函数用 ReLU,输出层用 tanh 激活后乘以动作上限。Critic 网络构建上,我同样用两层全连接,输入是观察量和动作拼接后的向量,输出是 Q 值估计。DDPG的探索噪声选择了 OU 噪声,衰减系数设为 0.995,这样训练中后期探索幅度会自然下降,策略趋于稳定。
下面是训练相关的完整配置参考:
| 配置项 | 取值 |
|---|---|
| 控制器采样周期 | 0.001s |
| RL决策周期 | 0.01s |
| Actor网络 | 两层全连接,每层128神经元 |
| Critic网络 | 两层全连接,每层128神经元 |
| Actor学习率 | 1e-4 |
| Critic学习率 | 1e-3 |
| 经验池容量 | 1e6 |
| 批量大小 | 128 |
| 折扣因子 | 0.99 |
| 扰动噪声 | OU噪声,衰减系数0.995 |
4. 训练收敛与结果对比:固定参数SMC与DDPG自适应SMC的差异
整个训练过程大约跑了 1200 个episode。前 200 个episode里,累积奖励基本贴着最低值来回波动,这是DDPG探索阶段的特点,动作里噪声占主导,控制器参数经常被试探性推到边界。如果没有参数上下限和增量限幅,这个阶段很容易直接把仿真打爆。200到600个episode之间,平均奖励开始出现明显上升趋势,但单episode曲线波动仍然很大。600个episode以后,策略基本稳定,参数修正量逐渐变成小幅度微调。这里提醒一句,不要看到单个episode的奖励上涨就急着停止训练,要看滑动平均曲线,否则很容易被偶然波动误导。
测试阶段我分别跑固定参数SMC和DDPG自适应SMC,注入完全相同的扰动信号组合,包括周期性正弦扰动和脉冲型突变扰动。固定参数SMC的跟踪误差基本在 ±0.3 附近跳动,控制量伴随明显的高频抖动,尤其在脉冲扰动出现的瞬间,恢复时间大约要 0.8 秒。DDPG自适应版本在扰动阶段会临时增大切换增益,把误差压制到 ±0.1 以内,等扰动消失后又主动降低增益,控制量曲线明显平滑。滑模函数 s 的轨迹也比固定参数版本更快收敛到零邻域,说明智能体在训练中确实学到了“扰动到来时加强切换项,扰动消退后减小切换项”这一符合直觉的策略。
更有意思的是把DDPG决策周期内的参数变化量完整记录下来之后,能直接看到智能体学到的东西。它倾向于在误差较大时同时增大 c 和 k,提高响应速度和抗扰能力;在稳态阶段把 delta 稍微放宽,换取更小的抖振。这个行为几乎就是工程师手动调参的“不调皮版”。它证明了一件事:强化学习在这个场景里没有玄学,它只是在奖励函数引导下找到了一条符合目标偏好的调节路径。反过来也提醒我们,奖励函数里如果没给抖振惩罚,它学出来的就是纯高增益策略,因为最小化误差的目标导向决定了它会追求极致收敛速度。
对比参数选择上,固定参数SMC我是参考常规经验值设定 k=8、c=10、delta=0.05,在这个参数下固定参数的性能已经算不错了,仍然被自适应版本全面压制。这说明参数在线调整带来的收益不是微小的补丁式提升,而是整个控制性能包线的一次扩展。
5. 仿真过程中的坑与心得:训练不收敛时的排查步骤和配置建议
第一个必须强调的是RL决策周期和控制周期的关系。DDPG智能体不需要在每个微小仿真步长都更新参数,这一点我在第 3 节里虽然没有展开,但它对训练稳定性影响非常大。建议把智能体的决策周期设置成控制周期的整数倍,比如控制周期 0.001s、RL决策周期 0.01s。原因很简单:控制系统的动态响应需要一个过程,动作改变后需要若干个控制周期才能体现效果。如果智能体每个控制周期都修改参数,经验池里的“状态-动作-奖励”相关性会非常差,训练曲线基本没法收敛。把决策周期放长之后,训练稳定性提升非常明显,这是我在这个项目里感触最深的一个调整。
第二个坑是奖励数值的量级控制。训练不收敛很多时候不是算法的问题,而是奖励数值太大或者太小。DDPG的Critic网络要拟合Q值,如果奖励绝对值长期处在1e4这个量级,梯度更新很容易出现振荡,甚至把之前学好的网络参数直接覆盖掉。建议把单步奖励的量级控制在个位数,误差项先做归一化再乘权重。比如用 e/(|e_max| + epsilon) 代替直接平方,这样后期Q值的量级不会崩,训练曲线也不会出现忽高忽低的剧烈波动。
第三个坑是训练初期的安全防护。训练最开始那几十个episode,智能体完全是在盲试,如果没有参数上下限和变化率限幅,系统很容易在某个组合下发散。我给Actor输出加了参数限幅之后,即使在最差情况下被控对象也只是跟踪偏差偏大,而不会直接发散,保证了训练可以持续进行。另外一个非常实用的做法是:训练的前100个episode 用较小的OU噪声方差,先把基础策略探索出来,之后再逐步加大噪声幅度,寻找更精细的策略。这种探索退火策略在参数化控制问题里比固定噪声更稳。
如果你只是刚开始尝试DDPG-SMC联合仿真,我最后再补一条建议:不要一上来就挑战高维系统和高复杂度工况。先把对象模型选成简单的二阶确定性模型,固定两个维度的参数,只让智能体调一个参数,比如先只调边界层厚度 delta,验证整个通道能跑通、能收敛、能看到效果,再逐步放开参数维度。我最初就是在模型里同时加入扰动和参数不确定性,结果训练时间翻了好几倍,问题还没排查清楚。后来老老实实从单参数调节起步,逐步增加复杂度,反而顺利得多。控制算法和强化学习的组合项目,最忌讳的就是一步到位,渐进式搭建才是工程上最稳妥的路径。