ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Simulink仿真通信延迟下多智能体轨迹一致性分析

Simulink仿真通信延迟下多智能体轨迹一致性分析 在真正开始搭 Simulink 模型之前我想先聊聊最让人头疼的那个现象为什么你写好的多机一致性控制器在理想仿真里能整整齐齐收敛一旦把通信延迟加进去状态曲线就开始像“呼吸”一样来回荡延迟再大一点干脆直接发散我在做多智能体编队那段时间这个问题困扰了我很久。后来把“基于Simulink的通信延迟下多机轨迹一致性分析”整个流程从头到尾走了一遍才彻底搞清楚延迟是怎么破坏稳定性的也摸清了在Simulink里建模、扫参、复现临界点的套路。这篇文章就带你完整走一遍从一致性协议的原理、临界延迟的理论计算到Simulink框图搭建、延迟扫描实验再到结果分析和工程扩展。适合刚接触多智能体仿真、或者想把手头论文算法搬到Simulink里验证的读者有一点控制理论基础最好零基础的话照着我的模型结构也能把图跑出来。1. 先想清楚再建模一致性协议与通信延迟的本质1.1 多机轨迹一致性在仿真里到底在算什么事所谓多机轨迹一致性说人话就是有一组智能体编号1到N每个智能体有一个状态x_i这个状态可以是无人机的高度、AGV的位移、卫星的相位角甚至可以是分布式储能系统的荷电状态。我们的目标是通过局部信息交换让它们最终收敛到同一个值x_1 x_2 ... x_N如果你让每个智能体都“听所有人的话”直接用全局信息问题就变成了集中式控制分布式控制的意义就没了。一致性算法的核心魅力在于每个智能体只跟自己的邻居说话交换局部信息最终整个网络却能达成全局一致。这和蜂群、鸟群的行为逻辑很像单个个体只看附近几个同伴整个群体却能统一行动。最常见的动力学模型就是一阶积分器x_dot_i u_i其中u_i是第i个智能体的控制输入。所谓一致性协议就是把u_i设计成邻居状态差值的加权和u_i -Σ a_ij (x_i - x_j)这里a_ij是连接权重相邻就大于0不相邻就是0。你把u_i代进去整个系统的闭环方程就变成x_dot -L x这里的L就是图拉普拉斯矩阵Laplacian Matrix它在后面整个分析里都是主角。你可以这么理解这个协议每个智能体都在“往邻居当前状态的均值方向拉”就像几个人围成一圈每个人看着旁边人的位置然后往中间挪最后大家自然就凑到一块了。这是一致性分析里最经典的连续时间一阶模型。等你把这张图看熟了再去分析二阶积分器模型、编队控制、时变拓扑就顺了。1.2 通信延迟为什么是稳定性的杀手理想情况下闭环方程是x_dot -Lx这是一个普通的线性常微分方程只要网络连通拉普拉斯矩阵的非零特征值都是正的系统一定稳定收敛。但现实通信不是瞬时的。数据从智能体j传到智能体i中间要经过传感器采集、组包、无线发送、接收解包、协议栈处理这一套流程下来几十到几百毫秒的延迟很正常。问题就出在这你控制器里用的邻居状态其实是邻居在τ秒之前的状态不是当前状态。延迟进来之后闭环方程变成了x_dot(t) -L x(t-τ)注意这里的状态变量带上了时间延迟。系统从普通的ODE变成了一类时滞系统Delay Differential EquationDDE。在频域上看反馈通路里多了一个e^{-sτ}因子这相当于给整个回路额外引入了相位滞后。相位滞后会削弱系统的稳定裕度滞后到一定程度本来稳定的闭环极点就会穿越虚轴跑到右半平面系统就发散了。跟车场景能帮你快速建立直觉你跟着前车如果你看到前车刹车尾灯才踩刹车这中间已经晚了0.4秒。假如你是按“前车0.4秒前的位置”来决定自己的车速那么你跟车的反应节奏总慢半拍。一个人慢半拍问题不大一整列车队每辆车都慢半拍就容易出现“手风琴效应”——车距忽大忽小甚至首尾相接。多机一致性也一样通信延迟不会因为算法本身“设计得合理”就消失它是物理链路带来的硬约束。1.3 两种常用延迟模型别搞混我在读文献和做仿真时发现很多人把两种延迟模型混在一起导致理论算出来的临界延迟和仿真对不上。这里必须区分清楚。第一种是“全回路统一延迟模型”u_i(t) -Σ a_ij [x_i(t-τ) - x_j(t-τ)]它假设控制器自身状态和邻居状态都是延迟τ后的版本。闭环可以化简成非常漂亮的向量形式x_dot(t) -L x(t-τ)这个模型的优点是理论推导极简洁拉普拉斯矩阵直接参与闭环临界延迟有闭合解特别适合教学和快速验证。它对应的是“传感器到控制器的一整条数据通路都有相同延迟”的简化场景。第二种是“仅链路通信延迟模型”u_i(t) Σ a_ij [x_j(t-τ) - x_i(t)]它假设智能体对自己的状态测量是无延迟的只有邻居发过来的信息经过了通信延迟。这更接近真实情况你本地传感器读自己的位置是实时的但远端数据是延迟的。这个模型在Simulink里也能建闭环形式是x_dot(t) A x(t-τ) - D x(t)其中A是邻接矩阵D是度矩阵L D - A。注意它不能简单合并成-Lx(t-τ)仿真模型里需要用两路增益来分别作用在延迟信号和当前信号上。这两个模型的稳定性边界不一样工程上建议先按第一种模型把整体框架跑通、把理论临界算明白再切换到第二种模型做更贴近实际的验证。下面主体部分我以第一种模型为主线因为它的理论闭环结果简洁Simulink结构也干净第6章我再告诉你怎么把第二种模型改出来。2. 先算后仿临界延迟与拉普拉斯矩阵特征值2.1 从闭环方程到特征方程我个人经验是不要在Simulink里盲目拖模块、盲扫参数先把理论临界延迟算出来仿真才有参照系扫参时才知道该在哪个区间加密采样。这一步数学上不难但是信息密度很大。回到闭环系统x_dot(t) -L x(t-τ)对两边做拉普拉斯变换注意延迟项变换后有e^{-sτ}sX(s) - x(0) -L e^{-sτ} X(s)移项得到(sI L e^{-sτ}) X(s) x(0)系统的特征方程就是det(sI L e^{-sτ}) 0拉普拉斯矩阵L的特征值记作λ其中一个特征值是0对应一致性方向也就是所有状态相等的方向其余非零特征值都大于0。由于L和e^{-sτ}在这里是可交换的矩阵L乘以标量函数我们可以把特征方程简化为对每个特征值λ都成立的形式s λ e^{-sτ} 0这个式子表面简单但它是理解延迟稳定性的钥匙。2.2 临界延迟的推导过程在稳定边界上特征根会落在虚轴上也就是s jω。把这个代入上面方程jω λ e^{-jωτ} 0写成λ e^{-jωτ} -jω把指数项展开成三角函数λ cos(ωτ) - jλ sin(ωτ) -jω分别比较实部和虚部。实部要求λ cos(ωτ) 0因为λ0我们考察非零特征值所以必须cos(ωτ) 0也就是ωτ π/2 mπ, m 0, 1, 2, ...虚部要求-λ sin(ωτ) -ω即λ sin(ωτ) ω当ωτ π/2 2kπ时即m为偶数sin(ωτ) 1这时候λ ω是一个正实数的临界点。当m为奇数时sin(ωτ) -1这时λ -ω不是物理允许的正特征值所以舍去。于是临界点落在第一组上λ ω π/(2τ) 2kπ/τ其中k 0时对应最低的临界频率也是最危险的第一个穿越点。由此反解延迟τ π/(2λ)系统的所有非零模态都要满足这个条件所以保证闭环系统稳定的充分必要条件是τ π / (2 λ_max)这里的λ_max是拉普拉斯矩阵的最大特征值。这就是一阶积分器网络在统一通信延迟下最经典的临界延迟结论。你看它多漂亮只要算出拓扑图的拉普拉斯最大特征值临界延迟立刻得到。2.3 手算示例3节点全连接图我们用一个3节点全连接拓扑做例子每个节点与另外两个节点都相连连接权重都取1。邻接矩阵是A [[0, 1, 1], [1, 0, 1], [1, 1, 0]]度矩阵D 2I每个节点度数都是2所以拉普拉斯矩阵L D - A [[2, -1, -1], [-1, 2, -1], [-1, -1, 2]]你会观察到拉普拉斯矩阵每行和为0这是它永远有一个零特征值的原因。求特征值L的特征值为0, 3, 3其中3是二重根。所以λ_max 3临界延迟τ_max π / (2 × 3) π / 6 ≈ 0.5236 秒这个数字意味着延迟只要超过0.52秒左右系统就会失稳。我的仿真实验里τ 0.4秒时稳定但有明显振荡τ 0.5秒时收敛极度缓慢τ 0.55秒就肉眼可见地发散了和理论临界对得很准。再给几个常见拓扑的对照数据方便你在自己的模型里快速估算拓扑结构λ_maxτ_max3节点全连接30.5244节点链式3.4140.4604节点环网40.393N节点完全图权重1Nπ/(2N)这里有个反直觉的结论拓扑连得越密λ_max越大反而对延迟越敏感。想象一下全连接网络里每个智能体同时被好几个邻居的延迟信号拉扯相位滞后累积得快系统更容易在临界点附近摇摆。3. Simulink模型搭建从矩阵方程到可仿真框图3.1 先用MATLAB脚本把参数算清楚不要在Simulink界面里手敲拉普拉斯矩阵尤其是节点多了以后手敲必错。我的习惯是先在MATLAB脚本里把模型参数全部算好工作区变量直接供Simulink引用。这样改拓扑、改节点数、改权重都只是改脚本的事情。% consensus_params.m % 3节点全连接拓扑 N 3; A ones(N) - eye(N); % 全连接邻接矩阵对角线为0 D diag(sum(A, 2)); % 度矩阵 L D - A; % 拉普拉斯矩阵 tau 0.4; % 通信延迟先给一个低于临界的值 x0 [0; 1; 2]; % 三个智能体的初始状态 % 顺手算理论临界延迟 lambda_max max(eig(L)); tau_critical pi / (2 * lambda_max); fprintf(lambda_max %.4f, tau_critical %.4f s\n, ... lambda_max, tau_critical);运行这个脚本MATLAB会打印lambda_max 3.0000, tau_critical 0.5236 s。后面Simulink模型里的Gain矩阵、Transport Delay初值、Integrator初值全都可以直接引用工作区变量。3.2 最小可仿真模型积分器延迟矩阵增益对于统一延迟模型x_dot -Lx(t-τ)Simulink建模可以非常“向量化”不需要搭三个一模一样的子系统直接用一条三维向量信号线贯穿整个模型。打开Simulink新建模型然后按这个顺序添加模块Integrator积分器双击打开把Initial condition设为x0。这个模块输出就是三维状态向量x(t)。Transport Delay传输延迟把延迟时间设为tau输出就是延迟后的状态向量x(t-τ)。Gain增益把Gain值设成-L矩阵乘法模式默认K*u就行输入是延迟后的状态向量输出就是-Lx(t-τ)。Scope和To Workspace从Integrator输出端引出来做观测。连线顺序是Integrator输出 → Transport Delay输入 → Transport Delay输出 → Gain输入 → Gain输出 → Integrator输入需要注意的是Gain模块接收的是向量信号增益矩阵是3×3输入向量是3×1输出就是3×1Simulink会自动处理维度匹配。千万别在这里勾选什么“矩阵增益”的特殊选项默认的K*u就对了。你可能会问为什么没有加法器因为闭环方程里没有显式的输入项积分器的输入直接就是-Gain的输出-Lx(t-τ)所以一条闭合回路就够了。这个模型的简洁程度正是统一延迟模型的优势。3.3 Transport Delay参数避坑Transport Delay这个模块是连续时间延迟的模拟但很多人在它身上踩坑。三个参数必须认真设置。第一个是Initial input初始输入。默认值是0这意味着仿真开始后的τ秒内模块会一直输出0。如果你把x0设为[0;1;2]在前0.4秒里延迟模块输出的却是[0;0;0]系统一上来就被一个错误的“历史状态”驱动曲线开头会有一段假跳变。正确做法是把Initial input也设为x0让延迟模块知道“过去的τ秒内状态一直是x0”。第二个是Delay time延迟时间。这里可以直接填工作区变量tau或者填具体的0.4。注意这个模块只接受非负延迟。第三个是Initial buffer size初始缓冲区大小。Simulink要知道缓冲多少长度来存储历史信号。默认值在短时间仿真里够用但如果你把仿真时长拉得很长、或者延迟值比较大建议把这个值调大比如直接设成10000避免中间出现“缓冲溢出”导致数据丢失。严格来说Simulink的Transport Delay是连续时间模块的工程近似不是专业DDE求解器但对于我们这种固定延迟的一致性分析精度完全足够。还有一个代数环问题。有的读者抄网上的搭法先把状态信号直接乘增益再反馈导致出现代数环报错或者仿真被强制用近似算法解。统一延迟模型天然不存在这个问题因为反馈路径上有Transport Delay它把连续时间信号变成了历史信号代数环会自然断开。如果你用的是无延迟的理想模型就必须在反馈回路里加一个Memory模块或者在Gain后面加一个1/z单元来破环。3.4 观测设计Scope和To Workspace调试阶段直接用Scope看曲线最直观。双击Scope有三条输入线分别显示三个智能体的状态。为了让数据可以被脚本批量分析我强烈建议再加一个To Workspace模块Variable namexoutSave formatTimeseries或者Array如果选Array会在工作区生成一个矩阵每一列是仿真时间戳对应的状态向量配合Scope看一眼趋势配合脚本做误差分析两不误。写一个运行单个仿真的脚本% run_single.m sim(consensus_delay, 30); % 仿真30秒仿真结束后工作区会有tout和xout。用plot(tout, xout)就能画出三条状态曲线。注意如果模型名和你保存在磁盘上的文件名不一致要先去修改模型文件名Simulink对模型名和文件名的对应关系管得很严。4. 分段实验延迟从0到0.6看轨迹怎么变4.1 τ0基准平滑收敛先把tau设成0跑一遍30秒仿真。三个智能体初始状态是0、1、2因为网络是全连接的一致性收敛值就是这三个数的平均值1。曲线大概在1到2秒内就基本重合了没有任何超调这是典型的无延迟一致性曲线也是我们用来对照的基准。这里有一个可以顺手验证的细节因为闭环矩阵是-L系统时间常数由非零特征值决定λ3对应时间常数1/3秒所以1秒多收齐非常正常。看到这种曲线你才敢确认协议和模型搭建本身没有bug后面加延迟导致的任何奇怪现象都是延迟引起的而不是建模错误。4.2 τ0.3开始出现振荡把tau改成0.3仿真30秒。你会发现三条曲线不再单调收敛而是出现明显的衰减振荡。x1和x3会先反向拉开然后像拉锯一样逐步靠近最终还是收敛到均值1但收敛时间拉长到了67秒的量级。这个现象的本质是s -λe^{-sτ}这个方程的特征根已经离开负实轴变成了一对共轭复根系统在收敛的过程中开始“绕着平衡点转圈”。延迟越大根的虚部越大振荡频率越高实部的绝对值越小收敛就越慢。你可以这样感受延迟像在反馈回路上加了惯性系统“刹不住车”所以必须先冲过头再拉回来。4.3 τ0.45临界边缘的慢性子把tau改成0.45仿真时间要拉长到50秒甚至更长。这时候曲线已经非常难看振荡幅度大、衰减极慢。从理论上说τ0.45仍然小于临界值0.5236系统还是稳定的但稳定裕度已经非常小特征根离虚轴很近收敛过程接近“临界慢化”。工程上遇到这种情况你就明白了理论稳定不等于可用。你要求系统在10秒内完成编队结果延迟0.45秒时50秒都稳不下来这个指标已经废了。做实际系统时通信延迟的预算至少要留出理论临界值的50%裕量也就是说对于τ_max0.52秒的系统你能接受的通信延迟最好不要超过0.2到0.25秒。4.4 τ0.55和0.6亲眼看见发散把tau改成0.55再跑一次。这一次曲线不会再收敛三个智能体的状态开始呈现持续增大的振荡。有意思的是由于统一延迟模型满足x_dot总和 0三个状态的平均值始终保持在1附近但个体状态振幅会越来越离谱最终报出NaN或者干脆冲出去。τ0.6时发散得更快。如果你在仿真参数里把最大步长设得太小可能仿真耗时很长建议把相对容差设成1e-4然后设置仿真停止时间30秒你会看到振幅从一点点增长到“肉眼可见爆炸”的全过程。这个“平均不变、个体发散”的现象是理解时滞系统稳定性的关键视觉体验。记住这个画面后面分析控制器鲁棒性时你会反复用到它。4.5 用脚本批量扫参每次改tau手动运行太慢了工程上做延迟敏感性分析肯定要用脚本批量扫。我写了一个标准扫参脚本通过set_param修改模型中的延迟参数循环仿真把每次仿真的一致性误差保存下来% scan_tau.m model consensus_delay; load_system(model); taus 0:0.05:0.6; x0_str mat2str(x0); % 把初始状态转成字符串供set_param使用 results zeros(length(taus), 2); % 第一列tau第二列收敛时间 for k 1:length(taus) % 修改模块参数 set_param([model /Transport Delay], DelayTime, num2str(taus(k))); set_param([model /Integrator], InitialCondition, x0_str); % 运行仿真 simOut sim(model, ReturnWorkspaceOutputs, on, ... StopTime, 60, SaveOutput, on); xout simOut.get(xout); % 时间序列 tout simOut.get(tout); % 后续计算一致性误差见第5章 results(k, 1) taus(k); end注意两点set_param修改参数前模型必须已经存在所以先load_system每次仿真前要重置Integrator初值否则上一次仿真的终态会变成下一次的初态结果就乱了。这个脚本改一改就能做任何参数的单变量扫描。把结果汇总成一张表方便对照延迟τ/s现象观察2%误差带收敛时间/s0无超调平滑收敛约1.50.1轻微振荡约30.2明显衰减振荡约50.3强振荡、收敛慢约80.4振荡收敛约150.45临界慢收敛大于400.5临界边缘数值上难判定大于600.55发散不收敛0.6快速发散不收敛这组数据可以复制到你的实验报告或论文里作为“通信延迟影响一致性收敛性能”的直接证据。5. 看着轨迹说话一致性误差指标与时延关系5.1 用误差范数定义“一致程度”光看Scope曲线只能定性判断论文和工程汇报里需要定量指标。我最常用的是一致性误差E(t)定义成状态向量和其均值之间的欧氏距离E(t) ||x(t) - mean(x)·1||_2其中1是全1向量。E(t)0说明所有智能体状态完全相等E(t)0说明还在收敛过程中。这个指标的好处是它天然消掉了共识值的漂移只关注“彼此之间差多少”非常适合衡量一致性质量。在扫参脚本的循环里加上这一段x xout.Data; % 如果xout是Timeseries xm mean(x, 2); % 每一时刻的均值 E sqrt(sum((x - xm).^2, 2));然后你可以用semilogy画E(t)的曲线让衰减趋势变成近乎直线一目了然。你会发现无延迟时E是快速直线式衰减延迟越大这条直线斜率越缓甚至在临界点附近变成水平线。5.2 收敛时间的统一定义工程报告里光给E(t)曲线还不够需要给出一个标量指标。我建议用“2%误差收敛时间”从仿真开始到E(t)永久降到初始值的2%以下所需的时间。这个定义和控制工程里settling time的定义一脉相承——系统进入并保持在终值附近2%误差带内不再出来。写个小函数function t_settle settling_time(t, E, threshold_ratio) threshold E(1) * threshold_ratio; idx find(E threshold, 1, last); % 之后不能有超调 if isempty(idx) t_settle NaN; else t_settle t(idx); end end注意这个函数要保证“之后不再超过阈值”最稳妥的做法是从末尾往前找最后一个超过阈值的时刻然后之后的点都低于阈值。上面这个找法还需要细化工程里可以用find(E threshold, 1, last)如果为空说明从某个时刻起一直低于阈值取最后一个下降沿。第4章表格里的收敛时间就是这么算出来的。你会看到收敛时间随τ的增长不是线性的而是在临界点附近急剧恶化。τ从0.4到0.45延迟只加了0.05秒收敛时间却从15秒翻倍到了40秒以上。这说明临界点附近系统性能脆弱得惊人。5.3 仿真临界点 vs 理论临界点我用扫参脚本把τ的扫描步长细化到0.01秒发现仿真中看到的临界点基本在0.52附近和理论值0.5236非常接近。两者有小偏差的原因主要有三个第一Transport Delay模块是缓冲区近似数值上存在离散误差。第二Simulink的变步长求解器本身有误差容限在临界点附近特征根接近虚轴数值积分容易被“拖住”。第三判断发散与否依赖于仿真时长如果只跑30秒接近临界的系统看起来可能很像“没收敛”容易被误判为发散。所以在表述仿真临界点时我一般写成“理论为τ_max0.5236s0.52s处观察到振荡不衰减0.53s以上振幅增长”这样既严谨又不武断。5.4 一条重要经验别贴着临界值设计系统这章最后我想给一个血泪教训。我在一个编队控制项目里最初把通信延迟预算卡在理论临界值的80%结果实测系统因为传感器采样抖动、网络拥塞、协议栈不确定时延实际延迟比平均值大不少系统在跑了几十秒后开始出现持续振荡。后来我强制把预算压到理论值的50%振荡问题基本消失代价是拓扑不能连得太密。这背后的逻辑其实在第2章已经埋下伏笔τ越接近τ_max闭环特征根越靠近虚轴稳定裕度越小对外部扰动和参数摄动越敏感。理论临界值是理想化模型给出的天花板工程系统只配生活在天花板以下一半的高度。6. 从3节点到实际项目拓扑切换、非均匀延迟与加速验证6.1 换拓扑、加节点只需要改矩阵很多读者问我做的编队有8个节点甚至几十个节点这个模型还能用吗答案是可以。只要网络是无向固定拓扑统一一阶模型下Simulink框图结构完全不用变你只需要修改MATLAB脚本里的N和A算出新的L矩阵模型里的Gain会自动引用新的-L。比如把3节点换成8个节点的环形拓扑N 8; % 环形邻接矩阵 A zeros(N); for i 1:N A(i, mod(i, N)1) 1; A(i, mod(i-2, N)1) 1; end L diag(sum(A,2)) - A;然后算λ_max看理论临界延迟再跑仿真。整个过程不需要改变Simulink模型里的任何连线。这就是向量化建模的好处模型的复杂度不随节点数量增加而增加变的只是矩阵维数。节点数多了以后要留意Gain矩阵的维度和Integrator的向量长度Simulink在维数不匹配时会在编译阶段直接报错定位起来也不难。更大的规模建议用MATLAB Function模块写协议逻辑再用S-Function封装不过那就是另一个话题了。6.2 非均匀延迟从理想模型走向真实通信前面的统一延迟模型在理论上很漂亮但真实系统里每条通信链路的延迟几乎不相等。智能体1到智能体2的无线信道可能延迟80毫秒智能体2到智能体3可能要150毫秒而且这个延迟还在随时间抖动。要建更真实的模型就要切换到第1章提到的“仅链路通信延迟模型”。在Simulink里我们需要把状态信号分成多路每路经过不同的Transport Delay再按邻接矩阵叠加。对于N3的拓扑你可以给每个智能体单独建一个子系统子系统内部有自己状态的直通反馈乘以-D以及来自每个邻居的独立延迟支路乘以A的对应行。延迟不同的链路只需要给相应的Transport Delay设不同的DelayTime。如果延迟还是时变的可以用Variable Transport Delay把延迟时间作为外部输入信号提供给模块。这个模块比固定延迟复杂一些它的输入需要同时给信号和“延迟时间”而且延迟时间的导数有限制不能任意抖。实际工程中我更推荐先用固定延迟的蒙特卡洛扫描来测试系统对不同延迟组合的鲁棒性运行几十组参数取最坏情况比单纯做一次高精度时变延迟仿真更能暴露问题。6.3 外部模式、C代码生成和联合仿真的工程衔接最后聊两句工程衔接的事。Simulink模型调通之后最常见的两个诉求是“在线调参”和“部署到目标机”。MATLAB在这块的支持很成熟External ModeMonitor Tune可以让你在真实硬件上运行时通过上位机在线修改模型里的tau参数实时看轨迹曲线变化。调试通信延迟相关的控制器时这点非常有用因为真实延迟和仿真延迟的差异一眼就能看出来。如果要部署Embedded Coder可以把模型生成C代码直接烧到控制器里。但要注意Transport Delay在代码生成后会变成一块固定大小的缓冲区缓冲区长度必须能覆盖最大延迟时间否则运行时会丢数据。我在第一次做代码生成时就吃过亏仿真里好好的部署后跑几分钟状态突然跳变查来查去才发现是延迟缓冲溢出。一定要在代码生成的配置界面里检查Buffer size是否足够。如果你做的是智能车辆轨迹一致还可以把Carsim这类车辆动力学软件和Simulink联合起来Simulink跑一致性协议给出期望速度/加速度Carsim输出真实车辆动力学响应再把实际位置反馈回一致性算法。这种联合仿真能验证的就不只是算法层面的收敛性而是包含车辆动力学特性后的闭环性能。我现在做多机编队相关实验标准流程是先用Simulink把理想一致性跑通再算临界延迟定裕量然后用外部模式在线看真实延迟下的表现最后才生成代码部署。每往前一步模型离实际系统就近一步理论临界延迟始终是那个兜底的锚点。最后再分享一个小技巧给Simulink模型里的模块起名字尽量规范尤其是有多个Transport Delay、多个Gain的时候不然set_param的时候找模块路径会非常痛苦。我习惯把所有延迟模块统一命名成Transport Delay_N这种带编号的格式所有增益模块命名成Gain_L、Gain_D这种带矩阵含义的名字配合MATLAB脚本批量修改参数时省下的时间绝对对得起这几分钟命名功夫。
返回列表