简介:四旋翼飞行器MATLAB仿真程序包内含完整Simulink仿真系统与配套M脚本,面向无人机控制、飞行器建模方向的科研人员和学生,解决从动力学建模到控制算法验证的仿真需求。压缩包共17个文件,以15个m脚本和2个mdl模型为主,大小仅53KB,其中mdl搭建系统级仿真框架,m脚本负责参数初始化、控制律计算与结果可视化,分工清晰,便于按模块查阅。已有264人学习下载。程序包覆盖四旋翼六自由度动力学模型、旋翼升力与扭矩计算、PID或状态反馈控制器设计、陀螺仪及加速度计传感器模拟、轨迹规划等关键环节,并提供绘图脚本与滤波器实现,可对照学习姿态控制、速度控制、参数整定及数据滤波方法,通过仿真可直观观察不同控制参数下飞行姿态与位置的变化响应。程序包适用于课程设计、毕业设计以及无人机算法预研,可直接在Simulink中运行模型或配合脚本调整参数,为后续代码生成与硬件在环测试奠定基础。
1. 四旋翼MATLAB仿真能复现什么,先看清这个边界
拿到“四旋翼飞行器MATLAB仿真程序_包括simulink仿真系统和程序.zip”这类包,最常见的尴尬是:Simulink 模型能跑,但飞不起来,或者飞起来完全不像真机。原因基本一致——模型里缺了“力矩到转速的映射”这一层,PID 是按简化模型调的,传感器噪声又是理想白噪声。四旋翼仿真里,真正决定仿真可信度的不是 PID 写法,而是刚体动力学、执行器响应和状态估计三条线的对齐。这份标题对应的东西,本质上是把这三条线用 MATLAB 脚本和 Simulink 模型各实现一遍,再让脚本去改模型参数、批量跑仿真、抓数据回来分析。适合的读者是正在做飞控算法验证、比赛调参、或者毕业论文需要“仿真+实验对照”的人。注意边界:Simulink 模型不等同于实机飞控代码,它更适合验证控制律和估计器逻辑,而不是直接替代 PX4 或自研固件的硬件在环测试。
2. 四旋翼建模与 Simulink 模型结构:从六自由度刚体到控制量映射
2.1 坐标系和刚体动力学方程怎么落到 Simulink 模块
四旋翼仿真第一步是选坐标系。地面系建议采用 NED(北东地),机体系原点在质心,x 轴指向机头。姿态表达用 ZYX 欧拉角还是四元数,取决于你要不要做大幅度机动。做悬停和中小角度姿态控制,欧拉角直观且便于和 PID 参数对照;做大机动或想避免万向节死锁,就换成四元数。Simulink 里不自己推方向余弦矩阵,直接用 Aerospace Blockset 的坐标变换模块也能做,但自己写一个 3x3 旋转矩阵的 MATLAB Function 块往往更便于后期改造成自定义算法。
function R = euler2R(phi, theta, psi) % 按 ZYX 顺序构建旋转矩阵,输入单位:rad c1 = cos(psi); s1 = sin(psi); c2 = cos(theta); s2 = sin(theta); c3 = cos(phi); s3 = sin(phi); Rz = [c1 s1 0; -s1 c1 0; 0 0 1]'; % 注意 NED 系下偏航正方向 Ry = [c2 0 -s2; 0 1 0; s2 0 c2]'; Rx = [1 0 0; 0 c3 s3; 0 -s3 c3]'; R = Rz*Ry*Rx; end这段代码输出的是 DCM 矩阵的转置形式,因为 NED 系下欧拉角旋转顺序和内层 MATLAB 矩阵乘法的顺序需要对齐。很多第一次搭模型的人在这里栽跟头:R 用错了转置,导致推力方向投影反了,悬停控制指令全反。建议在模型初始化脚本里先做一次“欧拉角给角速度”的开环测试,对比手工算的数值结果。
刚体动力学方程在 Simulink 里用积分模块搭,控制输入是合外力 F 和合力矩 M。十二状态常用排列是位置 p(NED 坐标)、速度 v、欧拉角 Θ、角速度 ω。位置和速度的积分可以直接用 Integrator 模块,但角速度积分到欧拉角的转换要单独处理,因为欧拉角速率和机体角速度不是同一个向量。公式是:
dΘ/dt = R_rot * ω其中 R_rot 是欧拉角速率变换矩阵。这个矩阵在俯仰角 90 度时奇异,如果只做悬停和低速飞行问题不大,做特技就要换四元数。Simulink 里我一般用 MATLAB Function 块实现这个矩阵,避免把矩阵乘法写成四个独立积分器的散线。
2.2 力与力矩映射:四个电机转速如何变成油门和姿态控制量
四旋翼的电机输出到机体合力 F 与合力矩 M 的映射,是仿真的核心简化点。常见做法是忽略电机安装倾角和机架弹性,认为四个电机产生的升力 T_i = kf * w_i^2,反扭矩 M_i = km * w_i^2,kf 和 km 分别是升力系数和反扭矩系数。于是在这个假设下,总升力是四个升力之和,滚转力矩由左右电机差动产生,俯仰力矩由前后电机差动产生,偏航力矩由两组正反转电机的反扭矩差产生。写成矩阵形式:
% motor_mixing.m % 输入:四个电机转速 w(rad/s),输出:[F; Mx; My; Mz] kf = 1.2e-5; % 升力系数 N/(rad/s)^2 km = 2.5e-7; % 反扭矩系数 Nm/(rad/s)^2 L = 0.18; % 机臂长度 m w2 = w .* w; F = kf * sum(w2); Mx = L * kf * (w2(1) - w2(3)); % 1号和3号对角 My = L * kf * (w2(2) - w2(4)); % 2号和4号对角 Mz = km * (w2(1) - w2(2) + w2(3) - w2(4));这个映射表是按“X 型”机架写的,也就是机头在两臂之间。如果你手上的模型是“+”型,Mx 和 My 的表达式要换臂序。方向弄反的直接后果是滚转和俯仰控制量正负号冲突,仿真里会出现“推右杆向左转”的诡异现象。判断正负号的方法很简单:给 1 号电机一个阶跃转速增量,观察 Mx 的符号,再和 SolidWorks 或实物机架的电机序号图对照。
kf 和 km 两个系数不是随便拍出来的。如果包里没有提供真机辨识数据,先用经验值起步:以常见 250 级机架悬停油门 50% 左右为参考,配合电机最大转速 1000 rad/s 反推 kf。更准的做法是拿螺旋桨静拉力测试台的 CSV 记录,在 MATLAB 里用polyfit(log(w), log(T), 1)拟合指数,确认是否真的接近二次关系。螺旋桨在低转速区往往偏离二次模型,仿真中表现就是悬停点附近出现小幅振荡,此时把模型改成分段线性插值表会更稳。
2.3 Simulink 模型的推荐分层结构:控制器、执行器、刚体、传感器
拿到一个四旋翼 Simulink 模型,先看顶层是否按“控制器→混控器→电机执行器→刚体动力学→传感器”五层划分。常见的不靠谱模型会把 PID 输出直接当成升力和力矩送进积分器,中间绕过混控矩阵和电机一阶惯性环节,导致仿真曲线完美但上真机必炸。执行器模型至少应该包含两个环节:一个是转速环的等效一阶惯性,时间常数取 0.02~0.05 秒;另一个是转速到升力力矩的静态非线性映射。这两个环节是仿真和真机差异的最大来源。
电机执行器在 Simulink 里的标准写法是把控制器计算出的期望力/力矩送入混控逆矩阵,解出四个期望转速,再分别通过一阶惯性环节得到实际转速。注意混控矩阵不是方阵时要用伪逆,但四旋翼的力-力矩映射是 4 输入 4 输出,直接用矩阵除法即可。电机响应时间常数若没有实测,建议先取 0.03 秒,再用“扫参数”方式跑一个 0.02~0.06 的序列,观察姿态阶跃响应的超调量变化,这个操作在后面的调参章节会展开。
传感器层至少要有陀螺仪和加速度计,更完整的模型加磁力计和 GPS/IMU 融合。Simulink 里从“刚体动力学”输出的 Ω 和 a 是理想值,需要手动加传感器噪声和延时。常见做法是用 Random Number 模块生成白噪声,再经 Transfer Fn 模块做一阶低通整形,模拟 MEMS 陀螺的零偏不稳定性。这里建议把“理想真值”和“带噪测量值”用两条信号线分开走,控制器只接测量值,后处理分析用真值。两套信号都通过 Bus 打包,方便在 MATLAB 脚本里对照“估计误差”。
3. MATLAB 脚本驱动 Simulink:参数注入、批量仿真与数据回读
3.1 用 base workspace 统一管理模型参数,而不是在模块里写死
Simulink 模型里的 Gain、PID 模块可以直接写数字,但调参时你会后悔。更合理的做法是把所有可调参数定义成 MATLAB 脚本里的变量,模型内引用变量名,脚本通过assignin('base', 'Kp_att', 4.5)把值塞进 base workspace。这样批量调参的核心逻辑就变成:循环内改 workspace 变量,再调用sim函数跑一遍模型,从仿真输出对象里取出数据。模型里不写任何数字常量,包括质量和惯量也定义为变量。Simulink 模型初始化脚本Init_quad.m的结构大致是:
% Init_quad.m m = 1.2; % 质量 kg Ix = 0.012; Iy = 0.012; Iz = 0.024; % 惯量 kg*m^2 g = 9.80665; % 重力加速度 kf = 1.2e-5; km = 2.5e-7; L = 0.18; % 执行器映射参数 T_motor = 0.03; % 电机时间常数 s Kp_att = 4.5; Ki_att = 0.05; Kd_att = 1.2; Kp_rate = 0.8; Ki_rate = 0.03; Kd_rate = 0.06; % 传感器噪声方差 gyro_noise_var = 1e-5; accel_noise_var = 1e-3;每个参数上方都写单位,避免模型里把 kg 写成 g。惯量的单位是 kg·m²,角速度单位是 rad/s,PID 的 Kp 单位是 N·m/(rad/s) 这一类,写清楚单位在检查模型环节能省很多时间。建议这个初始化脚本和 Simulink 模型放在同一目录,并另写一个只有一行Init_quad的setup.m,用于 Ctrl+A 全选 F9 快速执行整个目录脚本。
3.2 用 sim 函数跑一次仿真并抓取多条信号的正确姿势
在 MATLAB 脚本里跑 Simulink 模型,最基础的是simOut = sim('quad_model'),但默认配置下输出数据格式不够友好。推荐先通过Simulink.SimulationInput对象指定参数和输出信号,再调用sim。这样可以绕开“模型里明明加了 Scope 但脚本里拿不到数据”的问题。看下面这段脚本,它示范了修改控制器参数、指定输出信号、跑完仿真后直接画图的典型三步:
% run_single_sim.m mdl = 'quad_model'; mdlWks = get_param(mdl, 'ModelWorkspace'); assignin(mdlWks, 'Kp_rate', 0.9); % 直接改模型工作区变量 assignin(mdlWks, 'Ki_rate', 0.02); simIn = Simulink.SimulationInput(mdl); simIn = simIn.setModelParameter('StopTime', '5'); % 只记录需要的信号,减少内存占用 simOut = sim(simIn); t = simOut.tout; phi = simOut.logsout.get('phi').Values.Data; theta = simOut.logsout.get('theta').Values.Data; psi = simOut.logsout.get('psi').Values.Data; figure; plot(t, phi*180/pi, 'r', t, theta*180/pi, 'g', t, psi*180/pi, 'b'); legend('roll(deg)','pitch(deg)','yaw(deg)'); grid on;这里强调Simulink.SimulationInput而不是set_param直接改模块参数,原因在于它可以把“参数快照”打包成对象,适合后面第 6 章要讲的parsim并行仿真。代码里每个变量的单位换算要留意:logsout里存的姿态角默认是弧度,画图前乘 180/pi 已经是基本素养。如果模型里既有欧拉角又有四元数输出,日志里会出现两组名字相近的信号,取数据时不要混用。
3.3 模型里设置数据记录:信号标记与日志选择器
Simulink 模型里想被脚本记录的信号,需要在信号线上右键选择“信号属性→记录”,或者用Simulink.sdi的 Mark 功能。推荐用“日志记录选择器”统一管理,而不是在模型里到处插 Scope 和 To Workspace 模块。在 R2023b 之后,Simulink 的信号记录标识更清晰,模型顶上工具栏“调试”页里可以直接勾选记录哪些信号。写模型时给每条重要信号取有意义的名字,例如phi_rad、phi_estimated_rad、F_desired_N,脚本里按名字取数据就不会出错。
数据记录还有一个容易被忽略的问题:仿真步长设置会直接影响记录的采样密度。默认的变步长求解器输出点是自适应加密的,这会让logsout数据长度变得不规则,做 FFT 或频域分析前必须重采样。常用做法是在脚本里对 t 做等间隔插值:
% 重采样到 100Hz 均匀网格 t_grid = 0:0.01:t(end); phi_resampled = interp1(t, phi, t_grid, 'linear');如果只是看阶跃响应曲线,不均匀采样问题不大;但如果要做功率谱密度分析或计算相位裕度,就必须按固定步长记录。这种情况下可以一劳永逸地把模型求解器改成固定步长ode4,步长 0.001 秒,和后面要介绍的控制器离散化周期保持一致。代价是仿真速度下降,但数据规整度带来的便利远大于这点开销。
4. 串级 PID 调参与仿真验证:从悬停到阶跃响应
4.1 姿态环加角速度环的结构和参数初始化
四旋翼控制器的主流结构是串级 PID:外环是姿态角环,输出期望角速度;内环是角速度环,输出期望力矩。两个环的带宽必须有差距,外环大约是内环的 1/5 到 1/3,否则两个环会互相激励,出现“滚转一机动就导致偏航抖振”这种耦合现象。Simulink 里搭建时,内环放在一个 Atomic Subsystem 里,外环放另一层,中间用 GoTo/From 或者 Bus 传递信号,不要画成一张大网。一个可用的初始化参数建议如下,后续按机架惯量缩放:
| 控制环 | 比例 Kp | 积分 Ki | 微分 Kd | 输出限幅 |
|---|---|---|---|---|
| 姿态角环 | 4.5 | 0.05 | 1.2 | ±45°/s |
| 角速度环 | 0.8 | 0.03 | 0.06 | ±10 N·m |
| 偏航角环 | 1.5 | 0.02 | 0.3 | ±45°/s |
| 偏航角速度 | 0.5 | 0.01 | 0.02 | ±3 N·m |
这里姿态角环 Kp 单位是 1/s,角速度环 Kp 单位是 N·m/(rad/s),注意换算。表格里的参数适用于质量 1.2kg、惯量 Ix=Iy=0.012 的小型穿越机模型,如果你拿到的包是更大轴距的机架,Kp 和 Kd 要按比例调整。一个粗略的换算关系是扭矩需求随惯量线性变化,所以 Kp 至少翻到惯量的比例倍数。
4.2 阶跃响应仿真怎么看:超调量、调节时间和振荡频率
调参数之前先定工况:给滚转角一个 10 度阶跃,记录 phi 的响应曲线。仿真时长取 3 秒,看三个方面:超调量是否小于 20%,调节时间是否在 0.8 秒以内,稳态误差是否在 0.1 度以内。如果超调大,先加角速度内环的 Kd,而不是去降外环 Kp。常见误区是通过疯狂降低外环 Kp 来压超调,代价是响应变慢、抗风性变差。正确顺序是:先调内环角速度环,让它能很快跟踪期望角速度且无振荡,再调外环角度环。Simulink 里可以通过在phi_ref信号处加一个 Step 模块做阶跃,也可以在第 3 章脚本里给它赋值一段阶跃序列。
振荡频率是另一个重要观察点。若 phi 曲线出现 3~5Hz 的等幅振荡,大概率是角速度环带宽太高,与机体振动模态耦合。此时把内环 Kp 向下调 20%,观察振荡频率是否移动。如果振荡频率反而升高,说明不是带宽问题,而是执行器延迟太大,需要减小电机时间常数 T_motor 或者降低内环 Kp。记录每次调参后的超调量和调节时间,形成如下表格式的记录:
# 调参记录示例,实际在总结脚本里输出 CSV {'Kp_rate': 0.8, 'overshoot_pct': 18, 'settle_time_s': 0.62, 'status': 'ok'}这个记录习惯在仿真阶段建立起来,后面上真机时可以直接复用同一套试验设计框架。仿真实质是在真机实验之前先做一遍最危险的参数扫描。
4.3 抗积分饱和与微分先行:两个最容易忽略的细节
积分饱和在四旋翼仿真里极其常见,尤其当期望角度比较大、输出限幅生效时。现象是阶跃响应超调严重,回落后又在另一侧出现反向超调,整个收敛过程拉长。Simulink 里处理方式有两种:PID Controller 模块自带 anti-windup 设置,在输出限幅勾选条件下选择 back-calculation 并给一个 Ki/Kp 比例系数;或者自己搭积分限幅。我倾向于用后者,原因是你可以在积分限幅里加入“与输出限幅方向相关”的条件,比通用模块更精细。
微分先行(只对测量值微分、不对期望值微分)适合用于姿态角环,因为姿态期望值经常以阶跃形式变化,若对误差直接微分,阶跃瞬间会产生尖峰控制量,激发执行器饱和。Simulink 里实现方式很简单:把 Kd 项的输入从“误差信号”改成“测量信号”再加负号,同时将一阶低通滤波器做在微分模块之后。这样控制器结构变成“PI 在误差上、D 在测量上”,仍然是标准的串级形式,但调参时物理含义更清楚。仿真里验证这一点的方法是对期望角度输入一个 5 度的快速阶跃,观察控制力矩输出是否出现超过限幅 3 倍的尖峰。若出现,说明微分项作用于误差而不是测量值。
5. 传感器噪声、风扰动与状态估计:让仿真更接近真机
5.1 陀螺仪和加速度计噪声模型的搭建方式
真实传感器数据由真值、常值零偏和随机游走三部分组成。Simulink 里如果只加一个 Random Number 到理想信号上,那是白噪声模型,忽略了零偏和温度漂移这两个更讨厌的因素。更合理的模型是:真值经过一个一阶低通滤波器(模拟带宽限制),然后叠加上由“Random Number 积分”产生的随机游走零偏,最后再加白噪声。陀螺的随机游走系数通常用噪声密度 S 表示,加噪模型如下:
% gyro_noise_model.slx 内部参数,或写入脚本 sigma_white = 0.003; % 白噪声 std,单位 rad/s sigma_bias = 0.01; % 零偏随机游走步长,单位 rad/s^2 bias_drift = 0.0; % 常值零偏,人为设定用积分模块对白噪声积分会得到随机游走,这个信号就当作“实时零偏估计量”加在真值上。仿真时间短于 10 秒时随机游走效果不明显,但长仿真或做 EKF 收敛性测试时,这层噪声模型是必须的。加速度计模型类似,但多了比力分解的步骤。比力 f = (R_eb * (a - g)),如果直接在 Simulink 里把 “身体坐标系加速度计输出等于机体加速度” 当成 1:1 关系,那是在骗自己。正确做法是从惯导方程反推比力,再经过噪声污染。
5.2 风扰动如何注入:从恒定风到湍流 Dryden 模型
风扰动对悬停仿真影响很大,最简单的是加恒定风速偏置,在 NED 系下给一个固定速度叠加到机体速度上,再计算气动阻力。更接近实际的湍流模型是 Dryden 频谱模型,MATLAB Aerospace Blockset 提供 Dryden Turbulence 模块,参数里需要设空速、飞行高度和风速强度。小型四旋翼飞行高度通常低于 20 米,低空风切变不能忽略,常用设置是水平风速 3~5 m/s,垂直风速 0.5~1 m/s。Simulink 里把风扰动加到刚体动力学模块的空速输入上,而不是直接加力,这样才能反映“风是改变气动速度”的物理过程。
如果只是验证控制器的抗风性,恒定风加正弦变化风就够用。风作为一个不可控但已知的输入,可以从 Simulink 的 From Workspace 模块引入预先生成的风速时间序列。建议预生成 30 秒以上的风速序列,避免仿真开始阶段出现阶跃跳变。风速时间序列可通过 MATLAB 脚本生成并保存成 MAT 文件,这样跑多组参数时风序列保持一致,保证对比实验的公平性。
5.3 扩展卡尔曼滤波:四元数状态加陀螺零偏估计的简化实现
状态估计是实机飞控的核心,也是仿真包里往往最粗糙的部分。Simulink 里装 EKF 大致分两步:状态模型部分用 MATLAB Function 块实现四元数运动学加陀螺零偏为状态,量测模型部分用加速度计观测姿态中的部分信息。状态向量选 7 维:四元数 q(4 维)加陀螺零偏 b(3 维)。时间更新用陀螺角速度减去零偏估计再代入四元数微分方程。量测更新用地磁或加速度计做参考向量,在低加减速条件下加速度计的比力方向近似等于重力方向的反向,因此可以用它来修正俯仰和滚转,而偏航在无磁力计时不可观。
我简化实现的 EKF 时间更新和量测更新核心如下:
function [q_next, b_next, P_next] = ekf_predict(q_curr, b_curr, P_curr, gyro_raw, dt_noise) % 输入:当前四元数、零偏、协方差矩阵、陀螺原始测量(包含噪声)、时间步长 % 输出:预测状态与协方差 omega_corrected = gyro_raw - b_curr; % 修正零偏后的角速度 Omega = [0, -omega_corrected(1), -omega_corrected(2), -omega_corrected(3); omega_corrected(1), 0, omega_corrected(3), -omega_corrected(2); omega_corrected(2), -omega_corrected(3), 0, omega_corrected(1); omega_corrected(3), omega_corrected(2), -omega_corrected(1), 0]; dq = (0.5*dt_noise) * Omega * q_curr(:); q_pred = q_curr(:) + dq; q_pred = q_pred / norm(q_pred); % 归一化,保证四元数约束 b_pred = b_curr; % 零偏随机游走模型,预测值不变 F = eye(7)*dt_noise; % 简化雅可比,实际还要算四元数部分导数 P_pred = P_curr + Q; % Q 为过程噪声矩阵 q_next = q_pred; b_next = b_pred; P_next = P_pred; end这里 F 矩阵写得太粗糙,但作为第一步验证逻辑可以这样起步。真正精度要求高时,应该用对四元数指数坐标求导的方式计算雅可比矩阵,或者直接用无损变换的 UKF 替代 EKF。注意 Q 矩阵维度必须和状态维度一致,四元数部分过程噪声约 1e-4,零偏约 1e-6,差两个量级是合理配置。EKF 在 Simulink 里的部署建议用 S-Function 或 MATLAB Function 块,但后者在变步长求解器下要特别小心dt的获取,建议改为固定步长 0.005 秒。
6. 代码生成前的模型整理与外部模式验证
6.1 怎么把仿真模型改造成能生成 C 代码的形态
做完了仿真验证、调好了 PID,下一步往往是想把 Simulink 模型生成 C 代码。这步如果一开始就往“能用”方向设计,过程会很顺;如果是事后改模型,会踩很多坑。第一个硬性约束是:模型里所有 MATLAB Function 块的内置代码必须支持代码生成,也就是不能用eval、assignin、save这类运行时函数。四旋翼模型里最容易违规的就是“把控制器增益写在 MATLAB Function 里”然后调用 workspace 参数,这导致生成的代码要么参数被硬编码,要么必须额外配置参数接口。推荐的形态是把所有 PID 参数用 Simulink 的 Parameter 对象定义,并在 External Port 里显式引出,这样生成的代码里会有对应的变量可直接被外部修改。
第二个约束是连续模块要改造成适合离散求解的形式。PID Controller 模块要选成离散时间域,采样周期设为 0.005 秒,生成代码频率就是 200Hz,而不是继续用连续域去生成代码。连续域模块在代码生成时往往变成一个大死循环,实时性完全没法保证。四旋翼的控制周期通常在 200~500Hz,姿态估计周期可以是 500Hz,两者要分开用 Rate Transition 模块做数据同步。生成代码前,先把模型里的 Scope、Display 这类可视化模块全部删除或旁路,它们不参与代码生成但会影响代码可读性。
6.2 用 Simulink 外部模式做参数在线调节,避免整天重新编译
Simulink 外部模式是通过 Target 语言编译器建立外部通信通道,把模型跑在低配置目标机上或由 xPC 传递时,在 PC 端 Simulink 里实时改参数、看波形。对四旋翼仿真模型,如果你只是想在生成代码前先看看离散模型在固定步长下的表现,一个最轻量级的用法是把模型编译成 S-Function 并在快速加速器模式下连外部模式连接。这样可以避免“每改一个参数就生成一次完整嵌入式代码”的漫长循环。
实际操作流程是:把模型配置为固定步长、ode4、步长 0.005 秒,再在“代码生成→接口”里勾选 external mode。然后点击“部署到硬件”,软件会先编译生成 C 代码,再通过 TCP/IP 或串口连接外部通信接口。连接上之后,Simulink 模型页面上树形的参数原位显示,直接双击 PID Gain 模块改数字或者滑块拖动,目标机上运行的代码参数即时更新。这个功能对调参验证特别解压,它让你像是在真机遥控器上拨参数一样快速迭代。注意外部模式对模型里的连续模块支持不完整,所以事先把所有连续模块离散化是硬前提。
6.3 批量参数扫描:用 parsim 并行跑 50 组仿真并输出对比数据
最后一个进阶用法,是把第 3 章的Simulink.SimulationInput和 MATLAB 并行计算工具箱的parsim结合,做批量参数扫描。比如需要验证“电机时间常数 T_motor 从 0.02 到 0.06 扫 20 组,每组对超调量和调节时间的影响”,普通 for 循环要串行跑 20 次,每次几分钟,体验很差。parsim可以在多个工作进程里同时跑多个 SimulationInput 对象,速度接近线性提升。
% batch_scan.m mdl = 'quad_model'; T_motor_vals = linspace(0.02, 0.06, 20); simInArr(20) = Simulink.SimulationInput(mdl); for i = 1:20 simInArr(i) = Simulink.SimulationInput(mdl); simInArr(i) = simInArr(i).setVariable('T_motor', T_motor_vals(i)); simInArr(i) = simInArr(i).setModelParameter('StopTime', '3'); end simOutArr = parsim(simInArr, 'ShowProgress', 'on'); % 从 simOutArr 里逐个取 logsout 数据做分析setVariable与第 3 章的assignin作用类似,但它不污染 base workspace,而是把变量打包在仿真输入对象里。跑完之后simOutArr是一个与simInArr等长的 SimulationOutput 对象数组,再用arrayfun或 for 循环提取每个仿真结果的超调量,最终画一条“超调量随电机时间常数变化”的趋势线。这种批量扫描每次跑完都应该自动输出 CSV 或 MAT 文件,文件名带参数和日期,防止后续分析时混淆。拿到 CSV 后,在 Excel 或 MATLAB 里做简单统计就能判断:当 T_motor 大于某个值时超调量急增,从而给真机选电机提供量化依据。
本文还有配套的精品资源,点击获取