
简介面向汽车工程专业学生、自动驾驶横向控制研发人员与控制工程师这份 PDF 文档围绕基于模型预测控制的二自由度车辆轨迹跟踪与车道保持展开重点解决 Simulink 环境下车辆横向动力学建模、MPC 控制器搭建与参数整定问题。内容从简化二自由度模型的状态方程与线性化处理入手延伸到预测时域、控制时域、权重矩阵设置以及执行器饱和限制对实际控制可行性的影响并结合单移线工况讨论仿真表现与调参思路。包内共 1 个 PDF 文件约 114KB体量轻便适合作为课程设计、算法预研或横向控制入门的案头参考。已有 63 人学习下载。读者可从中获得较完整的建模—控制—仿真链路参考理解跟踪精度与计算开销之间的权衡并借助常见问题与调参经验减少试错成本同时注意模型假设的有效范围及其对控制效果的影响。1. 从一次高速画龙说起这套 MPC 模型到底解决什么问题单移线工况跑到 80 km/h横向误差曲线开始规律地来回摆方向盘跟着一阵一阵地抽——不是发散就是难看。这种场面见得太多了第一反应往往是去翻 QP 求解器的迭代信息十有八九白忙一场。问题通常出在两处车辆模型在高速下已经出了线性区或者误差是在惯性系里算的而控制器以为是道路系。这套基于 MPC 的二自由度车辆轨迹跟踪与车道保持 Simulink 模型把横向动力学、预测模型、QP 求解、执行器饱和和 Frenet 坐标转换串成了一条完整链路适合做自动驾驶横向控制入门、课程设计也适合已经写过 PID 但想把前馈预判补上的人。2. 二自由度车辆模型把四个轮子压成四行状态方程二自由度不是“简化到不真实”而是把横向控制真正关心的两个量留下来质心侧偏角和横摆角速度。四个轮子的力被折算到前后轴轮胎用线性侧偏刚度代替换来的是模型可以在毫秒级完成一次线性化和离散化。代价是它只在侧向加速度 0.4g 以内可信这一点后面会反复提到。2.1 线性轮胎假设能撑多远轮胎侧向力写成Fy C_alpha * alpha其中alpha是侧偏角。前轮侧偏角由方向盘转角、质心侧偏角和横摆运动共同决定alpha_f delta - beta - lf*r/vx后轮没有转向输入alpha_r -beta lr*r/vx。把这两个式子代进横向力平衡和横摆力矩平衡就得到下面这组方程m*vx*(beta_dot r) Cf*(delta - beta - lf*r/vx) Cr*(-beta lr*r/vx) Iz*r_dot lf*Cf*(delta - beta - lf*r/vx) - lr*Cr*(-beta lr*r/vx)整理成状态方程后beta_dot和r_dot对beta、r、delta都是线性的系数里带vx。这就是为什么车速一变整个 A 矩阵就跟着变——它不是常数矩阵而是以车速为调度变量的 LPV 结构。线性假设的边界要用数字说话。侧偏角超过 4° 到 5°侧偏刚度开始明显下降对应到日常驾驶大约是侧向加速度 0.3g 到 0.4g。60 km/h 下单移线的峰值侧向加速度通常不到 0.3g模型够用80 km/h 急变道很容易冲到 0.5g这时候模型预测出来的横摆响应比实车大控制器以为车转得比实际多回正就过头画龙就是这么来的。参数按一套紧凑型轿车填换车型只要改这张表符号含义取值单位m整备质量1573kgIz横摆转动惯量2873kg·m²lf质心到前轴距离1.30mlr质心到后轴距离1.50mCf前轴侧偏刚度66800N/radCr后轴侧偏刚度62700N/radvx纵向车速60 km/h16.7m/sTs控制周期0.05s提示Cf、Cr是单轴总侧偏刚度不是单胎。如果拿到的数据是单胎刚度记得乘 2这个数错一倍稳态横摆增益会差出 20% 以上。2.2 状态空间与离散化c2d 这一步省不掉把方程写成矩阵状态取[y, psi, beta, r]前两个是位置和航向后两个是动力学状态输入只有前轮转角delta。横向位置对时间的导数在小角度假设下是y_dot vx*psi vx*beta航向角导数是psi_dot r。拼起来就是四个状态、一个输入的标准形式。function [Ad, Bd, Cd, Dd] build_bicycle_model(vx, Ts, p) % 线性二自由度车辆模型状态顺序 [y; psi; beta; r]输入 [delta] % y: 横向位置(m) psi: 航向角(rad) beta: 质心侧偏角(rad) r: 横摆角速度(rad/s) m p.m; Iz p.Iz; lf p.lf; lr p.lr; Cf p.Cf; Cr p.Cr; % 动力学系数全部随 vx 变化 a11 -(Cf Cr) / (m*vx); a12 -1 - (lf*Cf - lr*Cr) / (m*vx^2); a21 -(lf*Cf - lr*Cr) / Iz; a22 -(lf^2*Cf lr^2*Cr) / (Iz*vx); b1 Cf / (m*vx); b2 lf*Cf / Iz; % 状态矩阵[y, psi, beta, r] A [0, vx, vx, 0; 0, 0, 0, 1; 0, 0, a11, a12; 0, 0, a21, a22]; B [0; 0; b1; b2]; C eye(4); D zeros(4, 1); sys ss(A, B, C, D); sysd c2d(sys, Ts, zoh); % 零阶保持器离散化 Ad sysd.A; Bd sysd.B; Cd sysd.C; Dd sysd.D; end第一行和第二行是运动学A(1,2)vx对应航向角对横向位置的贡献A(1,3)vx对应侧偏角产生的横向速度这两个元素是“预瞄”能起作用的结构基础。第三、四行才是动力学a11到a22的量纲分别是 1/s 和 1/s²b1、b2是输入增益单位随输入定义走。c2d用zoh因为实际控制器在一个采样周期内保持转向指令不变这和零阶保持器的假设一致用tustin也能跑但低速时容易在高频段引入虚假相位。离散化不是可选项。把连续状态直接塞进预测模型等于每个预测步都在做一次连续积分10 步预测的耗时能涨到离散版本的数倍而且预测出来的状态序列和实际控制器执行序列对不上。实测中 20 步预测、0.05 s 步长离散版本单次求解 1.2 ms 左右连续版本会掉到 3 ms 以上仿真速度肉眼可见地变慢。车速是整个模型里唯一随时间明显变化的系数来源。常规做法是在每个控制周期用当前车速重建 A、B 并重新c2d也就是把非线性系统沿当前工作点做一次局部线性化。20 步预测内假设车速不变对 60 km/h 匀速单移线完全够用如果是加减速工况把预测时域压到 10 步以内或者把车速也塞进状态向量做增广代价是 QP 规模翻倍。2.3 先做一次开环阶跃确认参数没填错闭环跑之前先用开环阶跃把模型对一遍能省掉后面一大半的排查时间。给 5° 方向盘阶跃看横摆角速度的稳态值。理论值是r_ss / delta vx / (L K_us * vx^2) K_us (m / L) * (lr / Cf - lf / Cr)L lf lrK_us是不足转向梯度。按表里的参数算60 km/h 下 5° 阶跃对应的稳态横摆角速度大约在 0.18 rad/s 量级。仿真结果和这个数对不上多半是lf、lr填反了或者侧偏刚度少乘了 2。这个校核只花五分钟但能挡住后面几小时的“为什么跟踪不上”的自我怀疑。% 开环阶跃校核 p struct(m,1573,Iz,2873,lf,1.30,lr,1.50,Cf,66800,Cr,62700); vx 16.7; Ts 0.05; [Ad, Bd, ~, ~] build_bicycle_model(vx, Ts, p); sys_d ss(Ad, Bd, [0 0 0 1], 0, Ts); % 只取横摆角速度输出 [y, t] step(sys_d * (5*pi/180), 3); % 5deg 阶跃仿真 3 秒 fprintf(稳态横摆角速度 %.4f rad/s\n, y(end));ss(Ad,Bd,Cd,Dd,Ts)里的Cd只保留第四行是为了把输出直接对准横摆角速度省得再从状态里挑。step的第二个参数是仿真时长取 3 s 足够看到稳态。算出来的值和理论值偏差超过 10%别急着调控制器先回去查参数。3. MPC 预测矩阵与 QP 求解kron 只是写法condensed 形式才是关键MPC 在横向控制里做的事很朴素用当前状态往前推 N 步看看按不同转向序列走下去哪条路的横向偏差最小、方向盘动作最省然后把这条序列的第一个动作发出去下一个周期重来。真正要写对的只有一件事——把 N 步预测写成关于控制序列的二次型剩下的交给quadprog。3.1 condensed 形式把 N 步预测压成一个二次型递推展开预测方程x1 A*x0 B*u0x2 A^2*x0 A*B*u0 B*u1一直到xN。把所有预测状态竖着摞成X所有控制量摞成U就得到X Sx*x0 Su*U。Sx是 A 的幂次堆叠Su是块下三角的 Toeplitz 结构第 i 行第 j 列那块是A^(i-j)*B。代价函数写成J (X - Xref)*Qbar*(X - Xref) U*Rbar*U代进去展开关于U的二次项系数是Su*Qbar*Su Rbar一次项系数是Su*Qbar*(Sx*x0 - Xref)。这就是标准二次型quadprog直接吃。function [H, f, Aineq, bineq, lb, ub] build_qp(Ad, Bd, x0, xref, u_prev, p) % 构造 condensed QPmin 0.5*U*H*U f*U N p.N; % 预测时域 Nc p.Nc; % 控制时域第 Nc 个之后保持 nx size(Ad, 1); nu size(Bd, 2); % A 的幂次预先算好避免循环里反复做矩阵乘 Ap cell(N1, 1); Ap{1} eye(nx); for k 1:N Ap{k1} Ap{k} * Ad; end % Sx: nx*N × nx Sx zeros(nx*N, nx); for i 1:N Sx((i-1)*nx1:i*nx, :) Ap{i1}; end % Su: nx*N × nu*Nc第 Nc 步之后控制量保持 Su zeros(nx*N, nu*Nc); for i 1:N for j 1:min(i, Nc) Su((i-1)*nx1:i*nx, (j-1)*nu1:j*nu) Ap{i-j1} * Bd; end if i Nc % 保持段把后面各步的贡献累到第 Nc 个控制量上 for j Nc1:i blk (Nc-1)*nu1:Nc*nu; Su((i-1)*nx1:i*nx, blk) Su((i-1)*nx1:i*nx, blk) Ap{i-j1}*Bd; end end end % 权重矩阵按块对角展开 Qbar kron(eye(N), p.Q); Rbar kron(eye(Nc), p.R); H Su*Qbar*Su Rbar; H (H H) / 2; % 数值对称化quadprog 只读上三角 f Su*Qbar*(Sx*x0 - xref(:)); % 执行器绝对限幅 ±25deg lb -p.delta_max * ones(nu*Nc, 1); ub p.delta_max * ones(nu*Nc, 1); % 转角速率约束|u_k - u_{k-1}| ddelta_max D diff(eye(Nc)); Aineq [D; -D]; bineq [p.ddelta_max*ones(Nc-1,1) D(:,1)*u_prev; p.ddelta_max*ones(Nc-1,1) - D(:,1)*u_prev]; endAp这个 cell 数组是关键的性能细节。直接写Ad^i每一轮都做一次矩阵幂N20 时能吃掉一半的构造时间预存幂次后Su的填充变成纯查表乘。kron(eye(N), Q)生成的是块对角矩阵物理含义是每一步预测都用同一套权重Q 是 4×4展开后是 80×80。Su里那段保持逻辑容易被忽略。控制时域Nc小于预测时域N时第Nc步之后的控制量不再独立优化而是保持第Nc个值。这段累加就是把后面各步的A^(i-j)*B折到同一个决策变量上少了它Su的列数和U的维度对不上quadprog直接报维度错误。H对称化那行不是洁癖。浮点运算下Su*Qbar*Su会有微小的不对称quadprog默认只读上三角不对称的部分被丢弃后解出来的U和预期有偏差极端情况下会报“H 不是正定”的警告。加一行(HH)/2成本可以忽略。3.2 quadprog 参数逐项对H、f、Aineq、lb/ub调用这一步参数顺序错一个得到的结果看起来能跑但其实完全不对。标准形式是min 0.5*x*H*x f*x约束Aineq*x bineq、Aeq*x beq、lb x ub。options optimoptions(quadprog, ... Algorithm, interior-point-convex, ... % 小规模稠密 QP 更稳 Display, off, ... MaxIterations, 200, ... OptimalityTolerance, 1e-6); [H, f, Aineq, bineq, lb, ub] build_qp(Ad, Bd, x0, xref, u_prev, p); [U, fval, exitflag] quadprog(H, f, Aineq, bineq, [], [], lb, ub, [], options); if exitflag 0 delta_cmd u_prev; % 求解失败就保持上一拍别输出垃圾 else delta_cmd U(1); % 只取第一个控制量 endAlgorithm选interior-point-convex是因为这里的 QP 规模不大Nc5 时决策变量只有 5 个稠密内点法比trust-region-reflective更不容易在约束边界附近来回抖。Display设off是必须的Simulink 里每个周期往命令行打一行跑十秒仿真能刷出几百行。exitflag必须判。车速突变、参考轨迹曲率跳变、权重矩阵量级失衡都可能让 QP 在 200 次迭代内不收敛。这时候如果直接把U(1)发出去得到的是一个半成品解方向盘会突然来一下。保持上一拍的指令是工程上最保守也最常用的兜底。只取U(1)是滚动时域的定义不是偷懒。下一个周期状态更新了重新解一遍U(2)自然会被新的解替代。有人为了省算力把整段U存下来分步发那是在开环执行参考轨迹一变就翻车。3.3 Q 与 R 的量级关系先罚偏差再罚动作Q 是 4×4 对角阵对应[y, psi, beta, r]四个状态R 是标量或 1×1对应前轮转角。量级关系比绝对数值重要得多。权重项物理含义推荐初值调整方向Q(1,1)横向位置偏差10大了转向延迟小了压不住偏移Q(2,2)航向角偏差5与 Q(1,1) 保持 2:1 左右Q(3,3)质心侧偏角0.5抑制车身姿态别设太大Q(4,4)横摆角速度0.5振荡时适当加一点R前轮转角0.1方向盘抽就加大跟得慢就减小初值这样定的理由横向偏差是安全指标权重最高航向偏差决定车头朝向次之侧偏角和横摆角速度是姿态量权重给大了会让控制器过度保守转向变得迟钝。R 取 0.1比 Q(1,1) 小两个数量级意思是“宁可多打一点方向也别压线”。调的时候有顺序。先把 R 固定把 Q(1,1) 从 5 试到 20找到横向误差最小又不出现明显超调的点再固定 Q把 R 从 0.05 往上加加到方向盘不再高频抖动为止。反过来先调 R会陷入“加大 R 跟得慢、减小 R 抖得凶”的死循环。侧偏角约束建议做成软约束。硬约束在高速下容易让 QP 无可行解加一个松弛变量epsilon代价函数里补一项rho*epsilon^2rho取 1e4 量级既保证约束基本不被突破又留了退路。约束本身写成-5deg beta_k 5deg和 2.1 节的线性区边界对齐超了就是告诉控制器“模型在这儿不可信了”。4. Simulink 落地MPC 模块、执行器饱和与 Frenet 坐标转换模型在脚本里跑通和能在 Simulink 里稳定闭环中间还隔着几件事采样周期怎么分、执行器怎么限、误差在哪个坐标系里算。这三件事任何一件没做对现象都很像——车能跑但跑得不对劲。4.1 分层结构与求解器配置顶层按职责切成四块Ref_Path产生参考轨迹和参考状态Plant是二自由度模型MPC_Controller里放 MATLAB Function 模块调用上面的 QPSteeringActuator做限幅和速率限制。四个子系统之间只传总线信号别用goto/from到处飞线出了问题根本追不下去。采样周期要分层。车辆模型用 0.01 s 定步长积分控制器用 0.05 s两者是整数倍关系Simulink 自己会做速率转换。模型步长和控制器步长取成非整数倍比如 0.013 和 0.05速率转换模块会在每个控制周期插值预测模型拿到的状态和实际状态差一点误差曲线会带上高频毛刺。% 求解器与采样设置 set_param(mpc_lka, Solver, ode4, FixedStep, 0.01, StopTime, 15); set_param(mpc_lka/MPC_Controller, SampleTime, 0.05); set_param(mpc_lka/Plant, SampleTime, 0.01); % 执行器限幅 ±25deg速率 ±200deg/s set_param(mpc_lka/SteeringActuator/Saturation, UpperLimit, 25*pi/180); set_param(mpc_lka/SteeringActuator/Saturation, LowerLimit, -25*pi/180); set_param(mpc_lka/SteeringActuator/RateLimiter, ... RisingSlewLimit, 200*pi/180); set_param(mpc_lka/SteeringActuator/RateLimiter, ... FallingSlewLimit, -200*pi/180);ode4是四阶龙格库塔定步长比ode45更适合这种带离散控制器的混合系统变步长求解器会在控制器采样点附近反复试探步长仿真时间能翻三倍。FixedStep取 0.01 是经验值车辆模型最快的动态是横摆时间常数在 0.1 s 量级步长取它的十分之一足够。RateLimiter的两个参数单位是 1/s所以200*pi/180表示每秒 200 度。这个数不是随便填的电动助力转向的电机转速上限折算到方向盘大概在 150 到 250 度每秒之间取 200 偏保守。填成200而忘了乘pi/180等于限制到每秒 200 弧度限幅形同虚设模型里看不出任何差别实车一跑就是另一回事。4.2 执行器饱和为什么是 ±25°方向盘转角超过 ±25° 之后轮胎侧偏角基本都过了线性区边界模型预测的侧向力和实际差得越来越远。把这个限制同时写进两处Simulink 的 Saturation 模块管物理执行器QP 里的lb/ub管控制器输出。两处不一致会出怪现象——QP 允许打到 30°执行器只给 25°控制器以为自己的指令被执行了下一拍基于错误状态继续算误差越积越大。饱和模块放在速率限制之前。顺序反了速率限制先把阶跃指令削成斜坡饱和模块再削顶两个非线性叠在一起调试时很难判断到底是哪一个在起作用。注意Saturation 的上下限和 QP 里的delta_max必须用同一个变量源。手工在两处各填一遍改参数时忘掉一处现象是低速正常、高速突然失控。4.3 惯性系到道路系的坐标变换控制器关心的是“车离车道线多远”“车头偏了多少”这两个量在道路坐标系里定义而车辆模型输出的是惯性系下的x、y、psi。中间少一步转换弯道上就会出现那种经典现象直道跟得很稳一进弯车就开始画毕加索。function [ey, epsi, s] to_frenet(x, y, psi, ref) % ref: 参考路径离散点结构体字段 xr, yr, phir, sr % 先找最近点再在最近点切线上做投影 d2 (ref.xr - x).^2 (ref.yr - y).^2; [~, idx] min(d2); xr ref.xr(idx); yr ref.yr(idx); phir ref.phir(idx); dx x - xr; dy y - yr; ey -sin(phir)*dx cos(phir)*dy; % 横向偏差左正右负 epsi wrapToPi(psi - phir); % 航向偏差归一到 [-pi, pi] s ref.sr(idx) cos(phir)*dx sin(phir)*dy; endey的符号约定要在整条链路里统一。这里取“参考线左侧为正”和车辆坐标系的 y 轴方向一致如果仿真里发现横向误差的符号和实际偏移相反控制器会往反方向修正误差直接发散。wrapToPi不能省航向角在 ±pi 附近跳变时不做归一化epsi会突然从 3.1 跳到 -3.1QP 拿到一个巨大的误差方向盘会猛地一抽。最近点搜索用的是全局暴力遍历参考路径几百个点时够用。路径上千点每次控制周期遍历一遍会吃掉 1 ms 以上换成 KD 树或者以上一周期的最远点为中心做局部搜索能压到几十微秒。5. 避坑与排查五条踩坑记录下面这五条每一条都在仿真里真实出现过现象都很像“控制器没调好”但根因分布在模型、坐标、参数三个层面。按现象去猜原因比按顺序读文档快得多。5.1 模型与离散化环节的三条坑一连续模型直接进 MPC仿真慢到怀疑人生。现象是仿真跑到一半卡住或者十分钟才推进两秒。原因是把ss(A,B,C,D)的连续系统直接塞进了预测模型每个预测步都在做一次连续积分N20 时单次求解从 1.2 ms 涨到 4 ms 以上仿真速度掉到 0.5 倍速以下。解决就是 2.2 节那一步c2d用zoh并且把离散后的Ad、Bd缓存在Data Store Memory里别在每个控制周期重新算一遍。坑二车速固定在初值变车速工况直接失效。现象是匀速工况跟踪得很好一加个 0 到 60 km/h 的加速段前几秒还行后面横向误差越来越大。原因是 A、B 矩阵在初始化时用 60 km/h 算了一次就再没更新过实际车速已经降到 20 km/h模型里的1/vx项全错。解决办法是在控制器的MATLAB Function开头用当前车速重建模型并且对vx做下限保护max(vx, 3)防止停车时除零。坑三预测时域和控制时域的单位混了。现象是把N从 10 改到 20本来期待预判距离变长结果控制效果反而变差。原因是N是步数物理预判时间等于N*Ts。Ts0.05时N20对应 1 s改成N40就是 2 s预判太远模型在 2 s 后的可信度已经很低优化出来的控制量对当下没有意义。改N的时候顺手把N*Ts算出来写进注释这个习惯能省掉很多次自我怀疑。5.2 控制器与坐标变换环节的两条坑四忘了坐标系转换弯道轨迹像抽象画。现象是直道完美进弯后车身开始左右摆误差曲线在弯道段出现规律的锯齿。原因是控制器直接拿惯性系下的y和参考轨迹的y相减弯道上参考轨迹的y本身在剧烈变化减出来的“误差”根本不是横向偏差。解决就是 4.3 节那套 Frenet 转换先找最近点再投影。踩过一次之后我习惯在控制器入口加一句断言abs(ey) 3超过 3 米说明坐标系没转对直接报错停下来。坑五Q(1,1) 给太大转向出现明显延迟。现象是横向误差的稳态值很小但响应总是慢半拍方向盘的动作比参考轨迹滞后 0.3 s 以上。原因是Q(1,1)从 10 加到 50 之后控制器过度追求位置精度宁愿用大幅度的滞后修正也不肯提前小幅动作表现出来就是迟钝。解决是把Q(1,1)退回到 10 到 20 的区间同时把Q(2,2)航向权重适当提高让控制器更早地感知到车头朝向变化。这一条反直觉的地方在于权重给大不一定跟得紧可能会更慢。6. 调参与验证单移线工况把横向误差压到 0.15 米单移线是最适合做横向控制验证的工况目标轨迹是一段平滑的正弦衰减横向位移 3.5 m完成时间约 4 s既有稳定的直线段也有曲率连续变化的过渡段能同时看出跟踪精度和方向盘平顺性。验证流程按三步走。第一步只跑开环把参考轨迹和车辆模型单独连起来确认参考轨迹本身没有突变点phir连续、sr单调递增。第二步关掉 MPC用固定转角输入看车辆能不能大致沿着预期方向走这一步是为了排除模型符号错误。第三步才接上控制器先 40 km/h 跑通再逐级提速。同一套参数在不同车速下的表现差异很大这张表是实测记录车速预测时域 N最大横向误差方向盘峰值单步求解耗时40 km/h200.08 m3.2°1.1 ms60 km/h200.15 m5.8°1.3 ms60 km/h100.22 m7.4°0.8 ms80 km/h200.31 m周期性振荡9.4°1.4 ms80 km/h20 侧偏角软约束0.19 m8.1°1.6 ms60 km/h 下把预测时域从 10 提到 20最大横向误差从 0.22 m 降到 0.15 m代价是单步求解时间从 0.8 ms 涨到 1.3 ms涨幅约 60%。这个交换在控制器算力有余量时是划算的但如果目标硬件是几十微秒级的嵌入式平台就得反过来想——把Nc压到 3把Su的构造预先算成常量表用查表代替在线矩阵乘能把耗时压回 0.6 ms 左右误差回升到 0.18 m仍在可接受范围。80 km/h 那一行是重点。误差不降反升曲线出现周期性振荡周期大约 0.8 s。根因是轮胎进了非线性区模型预测的横摆响应偏大控制器每拍都过度修正。加侧偏角软约束之后误差降到 0.19 m振荡幅度明显减小但没完全消失——这说明软约束只是缓解真要根治得换非线性轮胎模型或者三自由度模型。最后一个技巧关于怎么判断“约束是不是设太紧”。把每一拍的预测状态序列录下来在Workspace里画成动画横轴是预测步纵轴是横向偏差。正常的预测轨迹应该是一条平滑收敛的曲线如果蓝色预测点在中段突然集体折向说明约束在某一步把可行域切掉了控制器被迫走一条折线。这时候先松侧偏角约束再松速率约束别一上来就动 Q 和 R。从那以后我每次改完权重都先把模型开环扫一遍阶跃再进闭环跑单移线最后才上变速工况。这套顺序看着笨但能把“到底是模型错还是参数错”这个问题在十分钟内定位清楚。希望帮到你。本文还有配套的精品资源点击获取