当 `Bm` 矩阵为 4x3 矩阵时,需要对原代码中的部分内容进行修改以适配新的矩阵维度。以下是修改后的 `SpeedCurrent_MPC_Simulink` 函数代码:
```matlab
function uq = SpeedCurrent_MPC_Simulink(omega, iq, p, r)
% 带速度和电流约束的非级联MPC(PMSM专用),兼容Simulink代码生成
% 输入: omega(当前速度, rad/s), iq(当前q轴电流, A), p(当前位置, rad), r(位置参考, rad)
% 输出: uq(q轴电压指令, V), ud_comp(d轴电压补偿, V,此处设为0,可扩展)
%% 0. 显式初始化所有变量(优先级最高,解决未定义错误)
% 输出变量初始化
uq = 0.0; % q轴电压指令(标量,double)
ud_comp = 0.0; % d轴补偿(固定为0,标量,double)
% 输入变量类型转换(按实际输入格式调整,此处转为single)
omega = single(omega);
iq = single(iq);
p = single(p);
r = single(r);
% 中间变量预初始化(核心修复:确保所有变量有初始值)
Nc = 16; % 控制时域需提前定义(用于Delta_U尺寸)
Delta_U = zeros(Nc, 1, 'double'); % 二次规划输出(Nc×1,double)
Delta_uq = 0.0; % q轴电压增量(标量,double)
uq_current = 0.0; % 当前q轴电压指令(标量,double)
uq_prev = 0.0; % 前一时刻电压(适配persistent初始化)
%% 1. 关键参数定义(预定义所有常量,避免未定义错误)
% 采样与硬件参数
Tms = 0.001; % 采样时间 (s)
u_max = 310.0; % 最大相电压(380V电网→直流母线√2×220≈310V)
id = 0.0; % d轴电流指令(表贴式电机弱磁前设为0,double)
% 电机参数(根据实际PMSM调整,此处为示例值)
J = 0.020; % 转动惯量 (kg·m²)
B = 0.008; % 粘性阻尼系数 (N·m/(rad/s))
P = 4; % 极对数
Kt = 1.0; % 转矩系数 (N·m/A)
R = 0.4; % 定子电阻 (Ω)
Lq = 6e-3; % q轴电感 (H)
Ld = 6e-3; % d轴电感 (H)(表贴式电机Ld=Lq)
Psi_f = 0.186; % 永磁磁链 (Wb)
% MPC核心参数
Np = 24; % 预测时域(步数,需≥Nc)
% Nc已在开头初始化(控制时域,步数)
% 物理约束(硬件/安全限制)
omega_max = 3000.0; % 最大速度 (rad/s)
iq_max = 40.0; % 最大q轴电流 (A)
delta_uq_max = 20; % q轴电压增量约束 (V)
%% 2. PMSM状态空间模型(dq轴4阶模型:id, iq, omega, p)
% 状态方程:dx/dt = Am*x + Bm*u(u=[ud; uq; 新增控制量])
Am = [ -R/Ld, omega, -Psi_f/Ld, 0;
-omega , -R/Lq, 0, 0;
0, (3*P*Kt)/(2*J), -B/J, 0;
0, 0, 1, 0]; % 4×4状态矩阵(double)
% 输入矩阵(ud控制id,uq控制iq/omega,新增控制量)
Bm = [1/Ld, 0, 0;
0, 1/Lq, 0;
0, 0, 0;
0, 0, 0]; % 4×3输入矩阵(double)
% 输出矩阵(关注iq、omega、p三个被控量)
Cm = [0, 1, 0, 0; % 输出1:iq
0, 0, 1, 0; % 输出2:omega
0, 0, 0, 1]; % 输出3:p
ny = size(Cm, 1); % 输出维度(ny=3,double)
%% 3. 模型离散化(零阶保持ZOH,适配数字控制)
% 增广矩阵用于ZOH离散化:[Am Bm; 0 0](7×7)
aug_mat = [Am, Bm;
zeros(3, size(Am,2)+size(Bm,2))]; % 7×7增广矩阵(double)
M = expm(aug_mat * Tms); % 矩阵指数实现ZOH(double)
Ad = M(1:4, 1:4); % 4×4离散状态矩阵(double)
Bd = M(1:4, 5:7); % 4×3离散输入矩阵(double)
%% 4. MPC增广模型(状态+前一输入,实现增量控制)
% 增广状态:[id; iq; omega; p; uq_prev](5×1)
nx_aug = 5; % 增广状态维度
nu_aug = 1; % 控制输入维度(仅Δuq)
% 增广状态矩阵(5×5,double)
A_aug = [Ad, Bd(:,2); % 原状态对uq的响应
zeros(1, 4), 1 ];% 前一电压传递:uq_prev(k+1)=uq(k)
% 增广输入矩阵(5×1,double,输入为Δuq)
B_aug = [Bd(:,2); 1]; % 原状态对Δuq的响应 + uq(k)=uq_prev+Δuq
% 增广输出矩阵(3×5,double)
C_aug = [Cm, zeros(ny, 1)]; % 输出与前一输入无关
%% 5. 预测矩阵构建(Np步预测,double类型)
phi = zeros(Np*ny, nx_aug, 'double');
F = zeros(Np*ny, Nc*nu_aug, 'double');
for i = 1:Np
% 填充phi:第i步状态预测(A_aug^i * x_aug)
A_aug_pow = A_aug^i;
phi((i-1)*ny+1:i*ny, :) = C_aug * A_aug_pow;
% 填充F:第i步控制影响(仅控制时域内的Δuq)
for j = 1:min(i, Nc)
A_aug_pow_ij = A_aug^(i-j);
F((i-1)*ny+1:i*ny, j) = C_aug * A_aug_pow_ij * B_aug;
end
end
%% 6. 权重矩阵与参考轨迹(均为double类型)
% 输出权重矩阵Q_bar(对角矩阵,突出位置控制权重)
Q_iq = 8000; % iq权重
Q_omega = 8000; % 速度权重
Q_theta = 8000; % 位置权重
R_u = 0.01; % 增量权重(标量,double)
Q_bar = zeros(Np*ny, Np*ny, 'double');
for i = 1:Np
% 第i步的iq权重(Q_iq)和omega权重(Q_omega)
Q_bar((i-1)*ny+1, (i-1)*ny+1) = Q_iq; % iq权重
Q_bar((i-1)*ny+2, (i-1)*ny+2) = Q_omega; % omega权重
Q_bar((i-1)*ny+3, (i-1)*ny+3) = Q_theta; % p权重
end
% 控制权重矩阵R_bar(抑制电压增量波动)
R_bar = kron(eye(Nc, 'double'), R_u); % Nc×Nc对角矩阵(double)
% 参考轨迹生成(位置→速度→电流,强制double)
omega_ref = abs(r - p) ; % 由位置误差计算速度参考
omega_ref = max(min(omega_ref, omega_max), -omega_max); % 速度限幅
iq_ref = (J*(omega_ref - omega) + B*omega) / (3*P*Kt/2); % 转矩平衡求电流参考
iq_ref = max(min(iq_ref, iq_max), -iq_max); % 电流限幅
% 参考向量强制转为double(核心修复:避免r_seq为single)
ref_single = [iq_ref; omega_ref; r];
ref_double = double(ref_single);
r_seq = repmat(ref_double, Np, 1); % 扩展为Np步参考(double)
%% 7. 增广状态向量(当前状态+前一电压,double类型)
persistent uq_prev_persist; % 用persistent保存前一时刻电压
if isempty(uq_prev_persist)
uq_prev_persist = 0.0; % 首次调用初始化(double)
end
uq_prev = uq_prev_persist; % 关联persistent变量
% 增广状态:[id; iq; omega; p; uq_prev](强制double)
x_aug_current = double([id; iq; omega; p; uq_prev]);
%% 8. 二次规划问题构建(适配Simulink代码生成)
% 目标函数:min(0.5*ΔU'*H*ΔU + ΔU'*E)
H = F' * Q_bar * F + R_bar; % 二次项矩阵(Nc×Nc,double)
pred_error = phi * x_aug_current - r_seq; % 预测误差(double)
E = double(F' * Q_bar * pred_error); % 线性项(Nc×1,double,核心修复)
% 约束条件(电压增量限幅,double)
lb = -delta_uq_max * ones(Nc, 1); % 最小增量(Nc×1)
ub = delta_uq_max * ones(Nc, 1); % 最大增量(Nc×1)
% 优化选项(关闭显示,固定算法,适配代码生成)
options = optimoptions('quadprog','Algorithm','active-set');
% 求解二次规划(所有输入均为double,双重初始化Delta_U)
x0 = zeros(Nc, 1, 'double'); % 初始搜索点
Delta_U = zeros(Nc, 1, 'double'); % 再次初始化,避免歧义
Delta_U = quadprog(H, E, [], [], [], [], lb, ub, x0, options);
%% 9. 控制量计算与限幅
Delta_uq = Delta_U(1); % 取第一个控制增量(仅用控制时域第一步)
uq_current = uq_prev + Delta_uq; % 计算当前电压
% 电压幅值限幅(确保不超过直流母线电压)
uq_current = max(min(uq_current, u_max), -u_max);
% 更新前一时刻电压(供下一周期使用)
uq_prev_persist = uq_current;
%% 10. 输出赋值
uq = uq_current;
end
```
### 主要修改点:
1. **`Bm` 矩阵维度修改**:将 `Bm` 矩阵修改为 4x3 矩阵,以适配新增的控制量。
2. **增广矩阵维度修改**:由于 `Bm` 矩阵维度变化,增广矩阵 `aug_mat` 的维度从 6x6 变为 7x7。
###