资讯动态

基于滑模观测器与事件触发的多智能体分布式跟踪控制及仿真

发布时间:2026/9/7 2:39:53 来源:尧图企业网站定制
简介一份面向自动化控制研究人员与工程师的论文复现资料聚焦线性多智能体系统在状态不可测、外部干扰和网络带宽受限场景下的分布式鲁棒跟踪控制问题。核心方案包含三步设计基于邻居输出信息的分布式滑模观测器SMO以估计不可测状态并抑制外部干扰提出基于SMO状态的动态事件触发传输机制降低通信频率进而构建分布式鲁棒控制协议实现受扰线性多智能体系统的有界一致性跟踪。理论部分通过Lyapunov稳定性理论与Riccati方程推导保证系统稳定的充分条件。压缩包内含1个PDF文件约778KB完整覆盖滑模观测器设计、事件触发判据、控制律推导以及MATLAB仿真复现的详细代码注释从系统初始化、邻居通信加权、观测器更新到实际系统动态与性能评估均有逐段讲解并配有随机初始状态、正弦干扰等具体仿真参数便于读者对照理论动手运行和调参。该资源已吸引132人学习适合具备一定控制理论基础和MATLAB编程经验的研究者既能用于算法验证与优化也可作为多智能体系统相关课题的复现起点。 在实际工程里多智能体系统MASs的分布式跟踪控制一直是控制领域的热门方向不管是无人机编队、移动机器人协同还是智能电网里的分布式发电单元本质上都是让多个智能体通过局部通信实现对某个领航者leader的跟踪。但真上手做项目时会发现两个非常现实的问题一是很多被控对象的状态并不是全部可测的你手里往往只有部分输出信息二是智能体之间如果按照周期连续通信通信负担和能耗会非常夸张尤其在无线网络环境下数据碰撞和延迟会直接影响控制效果。我这次复现的论文方案正好把这两个问题放在一起解决——用滑模观测器SMO来重构不可测状态用事件触发通信来降低通信频率最后设计了分布式跟踪控制律并在Simulink/MATLAB里完成了全套仿真验证。这篇文章我会把从建模、观测器设计、控制律推导到事件触发机制、仿真代码实现、参数整定和踩坑记录的完整过程都讲清楚适合正在做多智能体方向毕业设计、论文复现或者想把这套方法迁移到自己课题里的同学。1. 问题描述与系统建模1.1 被控对象数学模型与通信拓扑论文里讨论的是线性多智能体系统这个线性不是指系统简单而是指每个智能体的动态可以用线性状态空间方程来描述。一般来说第i个跟随者智能体的模型写成dx_i/dt A*x_i B*u_i y_i C*x_i其中x_i是状态向量u_i是控制输入y_i是测量输出。领导者的动态类似但通常假设它不接收其他智能体的信息只按照自己的轨迹运动dx_0/dt A*x_0 y_0 C*x_0这里要注意一个关键细节系统矩阵A和输入矩阵B在跟随者和领导者之间是相同的这保证了跟踪问题有解。如果模型不匹配跟踪误差会存在稳态偏差那就需要引入额外的积分补偿或者扰动观测器复杂度会高一个量级。智能体之间的信息交互用图论来描述。每个智能体是一个节点通信链路是边。这里我用的是有向图因为在实际无线通信中智能体a能收到b的消息不代表b一定能收到a的单向链路更贴近真实场景。通信拓扑用拉普拉斯矩阵L来描述领导者与跟随者之间的连接用对角矩阵D来描述。复现时我选了4个跟随者加1个领导者的拓扑结构1号智能体只与领导者直接通信其他智能体通过邻居间接获取领导者信息。通信拓扑用邻接矩阵表示如下A_adj [0 1 0 0; 1 0 1 0; 0 1 0 1; 0 0 1 0];领导者连接矩阵D diag([1 0 0 0]);也就是说只有1号智能体能直接测量领导者状态其他智能体需要通过一跳或多跳获得领导者的信息。这种拓扑在分布式控制里非常典型因为如果所有智能体都能直接访问领导者问题就退化成集中式控制了。1.2 分布式跟踪控制目标控制目标是让每个跟随者智能体的状态x_i能够渐近跟踪领导者状态x_0也就是说对任意第i个跟随者跟踪误差要收敛到零lim(t→∞) ||x_i(t) - x_0(t)|| 0由于不是所有智能体都能直接访问领导者所以要定义局部跟踪误差用智能体自身状态与其邻居状态包括领导者如果可达的话的差值来构造e_i Σ_{j∈N_i} a_ij (x_i - x_j) d_i (x_i - x_0)这里的d_i是领导者连接矩阵D的对角元素表示第i个智能体能否直接测量领导者。这个e_i是分布式控制中的核心变量。可以证明如果全局的e向量收敛到零那么每个跟随者的状态就都收敛到领导者状态了。这个等价性证明在论文里是用克罗内克积和拉普拉斯矩阵的性质做的这也是为什么说通信拓扑的结构会直接影响系统的可跟踪性。1.3 系统的两大现实约束经典的多智能体跟踪控制假设所有状态都是可测的控制输入通过周期采样和持续通信来计算。但在工程实现中这两条假设往往站不住脚。第一状态不完全可测。很多实际系统只有部分输出可测量比如电机系统只能测转速但内部磁链测不到无人机能测位置和姿态角但速度分量可能噪声很大。直接拿部分状态去做反馈控制会导致性能下降甚至失稳所以必须设计观测器来重构完整状态。第二通信资源受限。如果按照固定周期持续通信每个智能体每个周期都要广播状态信息通信负载巨大。在无线自组网环境中这还会带来信道拥堵、数据丢包、竞争延迟等问题。而事件触发通信的核心思想是没必要就不通信只有满足特定条件才传输数据可以大幅降低通信频率。这两个约束也是本文选择SMO事件触发方案的根本原因。2. 滑模观测器设计与分布式控制律构造2.1 为什么选择滑模观测器状态观测器的选择其实有好几条路比如龙贝格观测器、高增益观测器、卡尔曼滤波、滑模观测器。我在复现中选滑模观测器主要基于三个原因一是鲁棒性强。滑模观测器对系统内部参数摄动和外部扰动有天然的抑制作用这个是滑模控制的固有特性。在设计时只需知道扰动的上界不需要精确的扰动模型这在工程上是非常实用的。二是有限时间收敛。传统龙贝格观测器的估计误差是按指数渐近收敛的理论上是无穷时间才完全收敛而滑模观测器在滑模面上可以在有限时间内到达收敛速度更快这对跟踪控制的动态响应有明显优势。三是结构相对简单。相比卡尔曼滤波需要求解Riccati方程滑模观测器的设计过程更加直观参数调节物理意义清晰适合工程调试。当然滑模观测器也有代价——符号函数带来的抖振chattering问题。后面会专门讲怎么抑制。2.2 滑模观测器的设计与增益推导针对第i个智能体设计如下形式的滑模观测器d(x_hat_i)/dt A*x_hat_i B*u_i G*(y_i - C*x_hat_i) K*sat(S_i)其中x_hat_i是估计状态y_i是实际测量输出sat(S_i)是饱和函数用于替代理想符号函数S_i是滑模面S_i y_i - C*x_hat_i观测器有三个关键项Ax_hat_i Bu_i是模型的名义动态用来大致预测状态演化G*(y_i - C*x_hat_i)是线性校正项其中G是观测器增益矩阵K*sat(S_i)是滑模切换项用于补偿模型不确定性和外界扰动。增益矩阵G设计为使得(A - G*C)是Hurwitz矩阵所有特征值都在左半平面。这一步可以用MATLAB的place命令或者LMI工具完成。参数K的选取要满足K η_max其中η_max是系统不确定性和扰动的上界。我在复现中取了K5扰动上界设为1留了充足裕度。如果K选得太小扰动补偿不足状态估计会有偏选得太大抖振会加剧后处理滤波也更麻烦。为了防止符号函数理想切换带来的抖振我用饱和函数代替理想符号函数sat(S) S / (|S| δ)其中δ是边界层厚度。δ越小越接近理想滑模但抖振越大δ越大抖振越小但估计精度会下降。这是个典型的权衡问题我在调试中取δ0.01时效果比较好。2.3 分布式控制律设计与滑模面构造有了状态估计之后控制律不能直接用真实状态误差而要用估计状态构造。这里要非常小心如果把估计误差直接忽略系统可能不稳定。严格的证明需要在李雅普诺夫分析里同时处理观测器误差和跟踪误差的耦合。定义局部估计误差为e_hat_i Σ_{j∈N_i} a_ij (x_hat_i - x_hat_j) d_i (x_hat_i - x_0)注意这里的领导者状态x_0被认为是已知的因为它由1号智能体直接测量或者由预设轨迹给定。控制律设计为u_i c * K_ctrl * e_hat_i其中c是耦合增益K_ctrl是控制增益矩阵。设计K_ctrl需要满足LMI条件。在我的复现中系统矩阵取为A [0 1; -2 -3]; B [0; 1]; C [1 0];即一个典型的二阶系统你可以把它想象成一个质量-弹簧-阻尼系统输入是力输出是位置。用LMI工具箱求解得到控制增益K_ctrl [3.0 3.5]耦合增益c 2.0。控制增益过大会导致系统过于激进容易触发不必要的通信事件增益过小则跟踪速度太慢。后面仿真部分会展示不同参数的效果。3. 事件触发通信机制设计3.1 连续通信的问题与触发控制思想传统分布式控制里每个智能体在每个控制周期都要向邻居广播状态信息然后接收邻居信息来计算控制输入。这种方式学名叫周期时间触发在理论分析里很简单但工程上资源浪费很严重。想象一下如果多智能体系统已经达到了一致状态所有智能体的状态都几乎相同此时还以固定频率互相广播数据意义何在事件触发控制的基本思想是智能体只在需要的时候才广播信息。怎么判断需要就是当本地信息与最近一次广播的信息偏差超过某个阈值时才触发一次新的通信。这样通信次数大幅降低同时系统稳定性依然有保证。3.2 触发条件设计与参数选取参考论文里常用的一种触发机制——基于状态误差的事件触发条件。第i个智能体在时刻t_k广播其信息之后不断测量当前状态与上次广播状态的差值e_i(t) x_hat_i(t_k) - x_hat_i(t)当这个测量误差的范数超过某个依赖于自身状态的阈值时就触发一次新的广播||e_i(t)|| σ_i * ||x_hat_i(t)||这里的σ_i是事件触发参数控制触发频率。我复现时取σ_i0.05。σ越小触发越频繁通信量越大系统性能越好σ越大触发越稀少通信节省明显但性能会有所下降。论文中通常证明了只要σ_i满足某个上界条件系统仍能保持稳定。还要注意避免Zeno行为即在有限时间内触发无限多次。这在理论上是个重要问题在仿真中通常通过设置最小触发间隔来防止t_next max(t_next, t_now T_min)我取T_min 0.01s既能防止Zeno行为又不至于影响控制性能。3.3 触发机制对稳定性的影响事件触发机制的设计需要保证在任意两次触发时间间隔内系统仍然是稳定的。这个证明通常构造一个包含触发误差的李雅普诺夫函数分析它在触发间隔内的衰减率。原理上不复杂核心在于找到一个合适的阈值上界使得触发误差引入的扰动可以被控制增益和耦合增益克服。从工程角度理解事件触发本质上是把连续的通信流变成了断续的数据包丢掉了那些变化不大的信息。如果数据变化很慢触发频率自然下降通信节省效果显著如果系统状态剧烈变化触发频率自动升高保证控制性能不丢失。这有点像视频编码里的动态码率控制——画面静止时降低帧率画面运动时提高帧率用有限的带宽资源换取可接受的质量。4. 仿真搭建与完整代码解析4.1 仿真环境搭建我用MATLAB R2022b做全部仿真纯脚本实现不依赖Simulink。这样做的优势是便于批量参数扫描和嵌套循环实验对复现论文里的一系列对比图表特别方便。仿真结构清晰地分成四层第1层是多智能体动态模型也就是每个智能体的状态方程第2层是SMO观测器每个智能体配一个独立估计自己的状态第3层是事件触发模块决定当前时刻是否需要广播数据第4层是分布式控制器根据邻居广播的信息计算控制输入。这四层结构在代码里用主循环来实现。4.2 完整MATLAB仿真代码下面给出我复现用的核心代码注释已经写得比较详细。% 基于SMO与事件触发的多智能体分布式跟踪控制仿真 % 4个跟随者 1个领导者 clear; clc; close all; %% 系统参数设置 A [0 1; -2 -3]; % 系统矩阵 B [0; 1]; % 输入矩阵 C [1 0]; % 输出矩阵位置可测速度不可测 n size(A,1); % 状态维度 N 4; % 跟随者数量 % 通信拓扑有向图 A_adj [0 1 0 0; 1 0 1 0; 0 1 0 1; 0 0 1 0]; D_leader diag([1 0 0 0]); % 仅1号智能体直接连接领导者 % 观测器增益 G_obs place(A, C, [-5 -6]); % 极点配置 % K 为滑模切换增益 K_sm 5; delta 0.01; % 饱和函数边界层 % 控制增益 K_ctrl [3.0 3.5]; % 状态反馈增益 c_gain 2.0; % 耦合增益 % 事件触发参数 sigma 0.05; % 触发阈值 T_min 0.01; % 最小触发间隔 % 仿真参数 T_sim 10; % 仿真时长 dt 0.001; % 积分步长 steps round(T_sim/dt); t 0:dt:T_sim; %% 初始化状态 x zeros(n, N); % 真实状态 x_hat zeros(n, N); % 观测器估计状态 u zeros(1, N); % 控制输入 x_broadcast zeros(n, N); % 上次广播的状态 last_trigger_time zeros(1, N); trigger_count zeros(1, N); trigger_times cell(N, 1); % 领导者轨迹 x0 [sin(t); cos(t)]; % 领导者状态轨迹随时间变化 % 随机初始状态有界 rng(42); x(:,1) [2; 0.5]; x(:,2) [-1; 1]; x(:,3) [3; -0.5]; x(:,4) [0; -1]; x_hat x 0.1*randn(n, N); % 初始估计误差 % 记录变量 x_all zeros(n, N, steps); x_hat_all zeros(n, N, steps); u_all zeros(1, N, steps); trigger_count_all zeros(N, steps); %% 主仿真循环 for k 1:steps t_now t(k); % 领导者状态 x0_now [sin(t_now); cos(t_now)]; for i 1:N % 1. 事件触发判断是否有新广播消息 trig_error norm(x_hat(:,i) - x_broadcast(:,i)); threshold sigma * norm(x_hat(:,i)); if trig_error threshold (t_now - last_trigger_time(i)) T_min % 触发通信更新广播状态 x_broadcast(:,i) x_hat(:,i); last_trigger_time(i) t_now; trigger_count(i) trigger_count(i) 1; trigger_times{i} [trigger_times{i}, t_now]; end % 2. 计算邻居信息总和 sum_neighbor zeros(n, 1); for j 1:N if A_adj(i,j) 1 sum_neighbor sum_neighbor x_broadcast(:,j); end end % 3. 构造分布式误差 e_hat (sum_neighbor D_leader(i,i)*x0_now) - ... (length(find(A_adj(i,:))) D_leader(i,i)) * x_hat(:,i); % 4. 计算控制输入 u(i) c_gain * K_ctrl * e_hat; % 5. 观测器更新滑模观测器 y C * x(:,i); % 测量输出仿真中用真实输出 y_hat C * x_hat(:,i); % 线性项 滑模切换项 dx_hat A*x_hat(:,i) B*u(i) G_obs*(y - y_hat) ... K_sm * sat_fun(y - y_hat, delta); x_hat(:,i) x_hat(:,i) dt * dx_hat; % 6. 被控对象真实动态加入扰动 d 0.5*sin(3*t_now); % 外部扰动 x(:,i) x(:,i) dt * (A*x(:,i) B*u(i) d); end % 记录 x_all(:,:,k) x; x_hat_all(:,:,k) x_hat; u_all(:,:,k) u; end %% 绘图 % 状态跟踪曲线 figure; for i 1:N subplot(2,2,i); plot(t, squeeze(x_all(1,i,:)), b-, LineWidth, 1.5); hold on; plot(t, x0(1,:), r--, LineWidth, 1.5); title([智能体, num2str(i), 位置跟踪]); xlabel(时间(s)); ylabel(x1); legend(跟随者, 领导者); grid on; end % 事件触发时间轴 figure; hold on; for i 1:N if ~isempty(trigger_times{i}) stem(trigger_times{i}, i*ones(size(trigger_times{i})), MarkerSize, 3); end end xlabel(时间(s)); ylabel(智能体编号); title(事件触发时刻分布); ylim([0 N1]); grid on; % 触发次数统计 figure; bar(1:N, trigger_count); xlabel(智能体编号); ylabel(触发次数); title(各智能体通信触发次数统计); grid on; %% 饱和函数定义 function s sat_fun(y, delta) s y / (abs(y) delta); end4.3 关键代码段深度解释这段代码里有几个地方容易被读者跳过但对复现成功至关重要。事件触发判断部分trig_error norm(x_hat(:,i) - x_broadcast(:,i)); threshold sigma * norm(x_hat(:,i));这个判断用的是估计状态不是真实状态。因为在工程场景下真实状态本来就不可测你只能基于观测器输出的估计值做判断。这一点和有些论文里直接用真实状态做触发纯理论分析可以是不同的复现时要注意别搞混。邻居信息和的符号问题e_hat (sum_neighbor D_leader(i,i)*x0_now) - ... (length(find(A_adj(i,:))) D_leader(i,i)) * x_hat(:,i);这里我直接用邻居状态的加权和减去入度乘当前状态数学上等于e_hat_i Σ_{j∈N_i} (x_j - x_i) d_i(x_0 - x_i)这个写法比直接遍历所有邻居计算差值要简洁很多也便于向量化优化。关键是符号方向先加所有邻居和领导者再减去当前状态乘以入度加连接数。正负搞反的话控制律就从负反馈变成正反馈系统必定发散。滑模观测器的数值积分dx_hat A*x_hat(:,i) B*u(i) G_obs*(y - y_hat) K_sm * sat_fun(y - y_hat, delta); x_hat(:,i) x_hat(:,i) dt * dx_hat;这里用的是最简单的欧拉积分。由于滑模项本身带有高频切换特性欧拉积分在步长较大时会产生比较明显的数值抖振。所以dt必须取得足够小。我试过dt0.01时观测器的输出有明显的高频毛刺改成dt0.001后曲线平滑了很多。如果你的论文复现对曲线平滑度要求高建议用ode45或者四阶龙格库塔法替代欧拉积分但会牺牲一些计算速度。5. 常见问题与复现避坑指南5.1 系统发散控制增益的调节方向我刚开始复现时把控制增益K_ctrl取得比较大期望跟踪速度能快一些结果系统直接发散。原因在于事件触发通信引入了额外的延迟和误差过大的控制增益会让触发误差被放大破坏稳定性条件。调试经验先把事件触发阈值设得非常小比如σ0.001让系统接近连续通信状态调好控制增益保证稳定然后逐步增大σ观察系统何时开始振荡或发散。找到临界值之后取一个安全裕度比如临界值的50%作为最终参数。这套方法虽然朴素但非常有效。5.2 观测器抖振严重抖振是滑模观测器的通病。如果状态估计曲线出现明显的高频振荡先检查边界层厚度δ是不是取得太小。δ从0.001调到0.01抖振幅度能减小一个数量级代价是稳态估计误差略微增大。但对跟踪控制来说这个误差通常可接受。另外还可以对滑模项做低通滤波或者用自适应滑模增益来进一步抑制抖振。论文里不一定会提这些工程技巧但仿真和实际应用中特别管用。5.3 事件触发频率过低导致性能下降如果触发阈值σ设得过大系统可能很长时间才通信一次这时跟踪误差会明显增大甚至出现阶梯状的跟踪曲线。这种现象的根源是两次触发间隔内控制器一直在用旧数据计算控制输入模型动态和真实状态之间的偏差越来越大。解决办法就是减小σ同时可以增加一项与跟踪误差相关的触发条件比如trig_error sigma * norm(x_hat) || trig_error eps_abs其中eps_abs是绝对误差阈值防止状态接近零时触发条件过于宽松。5.4 常见问题速查表为了方便快速定位问题我把复现中常见的异常现象、可能原因和解决办法汇总成一张表异常现象可能原因解决办法仿真直接发散输出NaN控制增益过大事件触发阈值过大降低K_ctrl和σ先用小σ验证稳定性状态估计曲线高频抖振δ过小K_sm过大积分步长太大增大δ至0.01左右减小K_smdt改为0.001跟踪有稳态静差扰动未被完全补偿滑模增益K_sm太小增大K_sm或加入扰动估计项触发次数过少跟踪呈阶梯状σ太大最小触发间隔T_min太大减小σ减小T_min触发次数过多事件触发退化为周期通信σ太小状态噪声大增大σ检查状态估计是否准确只有部分智能体收敛部分发散通信拓扑不连通领导者信息传播不到检查拉普拉斯矩阵是否连通增加拓扑连边观测器收敛慢极点配置位置太靠近虚轴把观测器极点配置到更远离虚轴的位置5.5 关于论文复现的几条核心建议复现论文最大的坑是参数和论文对不上。很多已发表论文并不会把所有参数完整列出有些参数藏在图表标题或仿真设置里需要仔细找。如果实在找不到我建议先按论文里给出的数值范围取中间值再通过仿真结果对比论文图表来反向调整。另外论文里的公式推导和仿真代码之间往往存在理解鸿沟——公式里用的符号和程序变量名完全不同。复现的时候别急着写代码先花两天时间把论文里的数学符号映射到代码变量把每个矩阵的维度、每个运算的次序理清楚再动手写。跳过这一步直接抄公式写代码调试时间至少翻倍。我之前复现过几篇多智能体方向的论文最大的感受是能不能复现成功一半取决于数学功底一半取决于调参耐心。如果第一次跑出来的结果和论文对不上不用慌先把触发条件、初始状态这些软参数逐项调一遍90%的问题都能用这个方法找到原因。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价